27 #include <Classes.hpp>
28 #include <Controls.hpp>
29 #include <StdCtrls.hpp>
31 #include <Buttons.hpp>
32 #include <ExtCtrls.hpp>
34 #include <Dialogs.hpp>
35 #include <Graphics.hpp>
36 #include <ComCtrls.hpp>
37 #include <Clipbrd.hpp>
61 #include <Filectrl.hpp>
64 #include <Vcl.HTMLHelpViewer.hpp>
65 #pragma package(smart_init)
66 #pragma link "Vcl.HTMLHelpViewer" //added at v2.0.0 for access to the .chm help file
67 #pragma resource "*.dfm"
87 Screen->Cursor = TCursor(-11);
153 "program operation may be restricted");
155 Application->HelpFile = AnsiString(
CurDir +
"\\Help.chm");
163 int DispW = (Screen->Width - 64) / 16;
164 int DispH = (Screen->Height - 192) / 16;
168 Display =
new TDisplay(
MainScreen,
PerformanceLogBox,
OutputLog1,
OutputLog2,
OutputLog3,
OutputLog4,
OutputLog5,
OutputLog6,
OutputLog7,
OutputLog8,
238 std::ifstream ConfigFile((
CurDir +
"\\Config.txt").c_str());
239 if(ConfigFile.fail())
242 SigImagePanel->Caption =
"Signals will be on the left hand side of the track";
248 "This program is free software released under the terms of the GNU General Public License Version 3, as published by the Free Software Foundation. " "It may be used or redistributed in accordance with that license and is released in the hope that it will be useful, but WITHOUT ANY WARRANTY; "
249 "without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details - " "you should have received a copy along with this program but if not see <http://www.gnu.org/licenses/>."
254 AnsiString ConfigStr =
"";
262 AnsiString ConfigValue = ConfigStr.SubString(9, ConfigStr.Length() - 8);
263 if(ConfigStr.SubString(1, 8) ==
"Signals=")
265 if(ConfigValue ==
"right")
277 SigImagePanel->Caption =
"Signals will be on the right hand side of the track";
286 SigImagePanel->Caption =
"Signals will be on the left hand side of the track";
293 if(ConfigStr.SubString(1, 8) ==
"BgndCol=")
297 if(ConfigValue ==
"white")
301 else if(ConfigValue ==
"blue")
306 if(ConfigStr.SubString(1, 8) ==
"RLYLocn=")
308 if(DirectoryExists(ConfigValue))
314 else if(ConfigStr.SubString(1, 8) ==
"TTBLocn=")
316 if(DirectoryExists(ConfigValue))
318 TimetableDialog->InitialDir = ConfigStr.SubString(9, ConfigStr.Length() - 8);
319 SaveTTDialog->InitialDir = ConfigStr.SubString(9, ConfigStr.Length() - 8);
322 else if(ConfigStr.SubString(1, 8) ==
"SSNLocn=")
324 if(DirectoryExists(ConfigValue))
330 while(!ConfigFile.eof());
427 SpeedButton96->Glyph->LoadFromResourceName(0,
"ConcourseGlyph");
491 FontButton->Glyph->LoadFromResourceName(0,
"FontGraphic");
492 HomeButton->Glyph->LoadFromResourceName(0,
"Home");
511 SetGapsButton->Glyph->LoadFromResourceName(0,
"ConnectGaps");
523 CallOnImage->Picture->Bitmap->LoadFromResourceName(0,
"CallingOn");
524 CrashImage->Picture->Bitmap->LoadFromResourceName(0,
"CrashWarning");
525 DerailImage->Picture->Bitmap->LoadFromResourceName(0,
"DerailWarning");
526 SignalStopImage->Picture->Bitmap->LoadFromResourceName(0,
"SignalStopWarning");
527 SPADImage->Picture->Bitmap->LoadFromResourceName(0,
"SPADWarning");
528 TrainFailedImage->Picture->Bitmap->LoadFromResourceName(0,
"TrainFailedWarning");
530 DistanceKey->Picture->Bitmap->LoadFromResourceName(0,
"DistanceKey");
531 PrefDirKey->Picture->Bitmap->LoadFromResourceName(0,
"PrefDirKey");
533 TrackLinkedImage->Picture->Bitmap->LoadFromResourceName(0,
"TrackLinkedGraphic");
535 GapsNotSetImage->Picture->Bitmap->LoadFromResourceName(0,
"GapsNotSetGraphic");
536 GapsSetImage->Picture->Bitmap->LoadFromResourceName(0,
"GapsSetGraphic");
547 AnsiString NL =
'\n';
548 const AnsiString TTLabelStr1 =
"Start new train" + NL +
"Start new service from a split" + NL +
"Start new service from another service" + NL +
549 "Start new non-repeating shuttle finish service" + NL +
"Start new shuttle train at a timetabled stop" + NL +
550 "Start new shuttle service from a feeder";
552 const AnsiString TTLabelStr2 =
"Pass" + NL +
"Be joined by another train" + NL +
"Front split" + NL +
"Rear split" + NL +
"Change direction of train";
554 const AnsiString TTLabelStr3 =
"Finish && form a new service" + NL +
"Finish && join another train" + NL +
"Finish && exit railway" + NL +
555 "Finish && repeat shuttle, finally remain here" + NL +
"Finish && repeat shuttle, finally form a finishing service" + NL +
556 "Finish non-repeating shuttle feeder service" + NL +
"Finish && remain here";
558 const AnsiString TTLabelStr4 =
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
559 "HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
" " +
562 const AnsiString TTLabelStr5 =
"HH:MM ';' Location" + NL +
"HH:MM ';' HH:MM ';' Location";
564 const AnsiString TTLabelStr6 =
"+ rear element ID - space - front element ID [+ optional ';S']" + NL +
"+ ref. of the train that splits" + NL +
565 "+ other service ref." + NL +
"+ shuttle service ref." + NL +
"+ rear element ID - space - front element ID ';' linked shuttle ref." + NL +
566 "+ linked shuttle service ref. ';' feeder service ref." + NL +
"+ location" + NL +
"+ joining train ref." + NL +
"+ new service ref." + NL +
567 "+ new service ref." + NL +
" " + NL +
"+ new service ref." + NL +
"+ ref. of train to join" + NL +
568 "+ list of valid exit element IDs (at least 1) separated by spaces" + NL +
"+ linked shuttle service ref.";
570 const AnsiString TTLabelStr7 =
"Arrival OR departure time (program will determine which from the context) + location." + NL +
571 "Arrival time, departure time (with no events between) + location";
573 const AnsiString TTLabelStr9 =
"Timetable entries" + NL +
"(service references etc.)";
574 const AnsiString TTLabelStr11 =
"Timetable" + NL +
"start time";
576 const AnsiString TTLabelStr12 =
"NB: WITHIN SERVICES commas must" + NL +
"not be used (have special meanings)," + NL +
577 "and semicolons may only be used to" + NL +
"separate service components.";
579 const AnsiString TTLabelStr13 =
"+ linked shuttle service ref. ';' finishing service ref." + NL +
"+ linked shuttle service ref.";
581 const AnsiString TTLabelStr15 =
"Repeat the service + ';' minutes between repeats ';' digit increment ';' number of repeats (last line of service)";
604 if((Screen->Width < 1024) || (Screen->Height < 768))
606 ShowMessage(
"Please note that this program works best with a screen resolution of at least 1024 x 768. Please change if possible");
611 WindowState = wsMaximized;
623 Screen->Cursor = TCursor(-2);
654 char *LocalNumericInformation = setlocale(LC_NUMERIC,
"");
656 if(LocalNumericInformation ==
"")
661 struct lconv *conv = &Locale;
667 catch(
const EFOpenError &e)
671 MessageDlg(e.Message +
" - program must terminate", mtError, But, 0);
672 Application->Terminate();
675 catch(
const Exception &e)
679 AnsiString Message =
"A fatal error occurred during the program setup process, the program must terminate. Message = " + e.Message;
680 MessageDlg(Message, mtError, But, 0);
682 Application->Terminate();
694 AnsiString ColourStr =
"", SignalStr =
"";
695 remove((
CurDir +
"\\Config.txt").c_str());
696 std::ofstream ConfigFile((
CurDir +
"\\Config.txt").c_str());
711 ConfigFile << AnsiString(
"Signals=") << SignalStr <<
'\n';
712 ConfigFile << AnsiString(
"BgndCol=") << ColourStr <<
'\n';
713 ConfigFile << AnsiString(
"RLYLocn=") << AnsiString(
LoadRailwayDialog->InitialDir) <<
'\n';
714 ConfigFile << AnsiString(
"TTBLocn=") << AnsiString(
TimetableDialog->InitialDir) <<
'\n';
715 ConfigFile << AnsiString(
"SSNLocn=") << AnsiString(
LoadSessionDialog->InitialDir) <<
'\n';
738 catch(
const Exception &e)
755 catch(
const Exception &e)
776 Screen->Cursor = TCursor(-2);
786 Screen->Cursor = TCursor(-2);
794 catch(
const Exception &e)
812 catch(
const Exception &e)
825 UnicodeString strVersion = L
"N/A";
827 VersionSize = GetFileVersionInfoSizeW(Application->ExeName.c_str(), &VersionHandle);
830 pBuffer =
new BYTE[VersionSize];
832 if(GetFileVersionInfoW(Application->ExeName.c_str(), VersionHandle, VersionSize, pBuffer))
834 VS_FIXEDFILEINFO *fi;
838 if(VerQueryValueW(pBuffer, L
"\\", (
void**)&fi, &buflen))
841 strVersion.sprintf(L
"%d.%d.%d", HIWORD(fi->dwFileVersionMS), LOWORD(fi->dwFileVersionMS), HIWORD(fi->dwFileVersionLS));
847 return(L
" v" + strVersion);
863 catch(
const Exception &e)
882 catch(
const Exception &e)
896 if(((TSpeedButton*)Sender)->Down)
907 Screen->Cursor = TCursor(-11);
908 InfoPanel->Caption =
"SELECTING: Filling area with chosen element";
909 bool FillSelectionFlag =
false;
912 UnicodeString MessageStr =
913 "Click 'Yes' to fill the area with the chosen element or 'No' to abort.\n" "Existing elements won't be overwritten although track can\n"
914 "have platforms and non-station named location elements added.\n\nThis message will not be shown again.";
915 int button = Application->MessageBox(MessageStr.c_str(), L
"", MB_YESNO);
918 FillSelectionFlag =
true;
923 bool TrackLinkingRequiredFlag =
true;
952 Screen->Cursor = TCursor(-2);
963 catch(
const Exception &e)
1005 ShowMessage(
"Incomplete track or other error - see inverted element (may be behind this message)");
1017 ShowMessage(
"Unable to set any track links");
1030 ShowMessage(
"Successful Completion");
1046 catch(
const Exception &e)
1067 catch(
const Exception &e)
1086 catch(
const Exception &e)
1105 catch(
const Exception &e)
1124 TFont *TempFont =
new TFont;
1132 TempText.
Font = DisplayFont;
1140 else if(Key ==
'\x1B')
1150 catch(
const Exception &e)
1169 catch(
const Exception &e)
1184 ShowMessage(
"Error, location name being entered without an entry in LNPendingList");
1204 Screen->Cursor = TCursor(-11);
1207 AnsiString ExistingName;
1221 UnicodeString MessageStr = UnicodeString(
"Another location named '") +
LocationNameTextBox->Text +
1222 UnicodeString(
"' already exists. If you continue its name will be erased. Do you wish to continue?");
1223 int button = Application->MessageBox(MessageStr.c_str(), L
"Warning!", MB_YESNO | MB_ICONWARNING);
1227 Screen->Cursor = TCursor(-2);
1238 bool UseExistingPosition =
false;
1247 if(ExistingName !=
"")
1251 UseExistingPosition =
true;
1255 Screen->Cursor = TCursor(-2);
1270 bool UseExistingPosition =
false;
1273 UseExistingPosition =
true;
1277 Screen->Cursor = TCursor(-2);
1290 LocStr = LocStr.Trim();
1299 if((LocStr !=
"") && (LocStr[1] >=
'0') && (LocStr[1] <=
'9'))
1301 Screen->Cursor = TCursor(-2);
1302 ShowMessage(
"Location name can't begin with a number");
1310 if(LocStr.Length() > 50)
1312 Screen->Cursor = TCursor(-2);
1313 ShowMessage(
"Location name too long, 50 characters maximum");
1321 for(
int x = 1; x <= LocStr.Length(); x++)
1323 char Ch = LocStr[x];
1324 if((Ch !=
' ') && (Ch !=
'&') && (Ch !=
'(') && (Ch !=
')') && (Ch !=
':') && (Ch != 39) && (Ch !=
'.') && (Ch !=
'-') && (Ch !=
'+') &&
1325 (Ch !=
'/') && ((Ch <
'0') || (Ch >
'9')) && ((Ch <
'A') || (Ch >
'Z')) && ((Ch <
'a') || (Ch >
'z')))
1327 Screen->Cursor = TCursor(-2);
1329 "Location name contains one or more invalid characters, must be alphanumeric, brackets, space, full stop, colon, inverted comma, '-', '+', '/' or '&&'");
1340 Screen->Cursor = TCursor(-2);
1341 ShowMessage(
"Location name cannot be 'cdt', this name would interfere with the timetable");
1352 bool UseExistingPosition =
false;
1353 if(ExistingName !=
"")
1357 UseExistingPosition =
true;
1361 Screen->Cursor = TCursor(-2);
1370 Screen->Cursor = TCursor(-2);
1373 catch(
const Exception &e)
1394 catch(
const Exception &e)
1408 int Dist = 0, SpeedLimit = 0;
1412 DistanceStr =
"No change";
1417 SpeedStr =
"No change";
1421 if(DistanceStr ==
"No change")
1425 if(SpeedStr ==
"No change")
1441 if(((Dist != -1) && (DistanceStr.Length() > 6)) || ((SpeedLimit != -1) && (SpeedStr.Length() > 6)))
1443 ShowMessage(
"One or more entries too long");
1447 if((DistanceStr ==
"") || (SpeedStr ==
""))
1449 ShowMessage(
"One or more entries blank");
1455 for(
int x = 1; x <= DistanceStr.Length(); x++)
1457 if((DistanceStr[x] <
'0') || (DistanceStr[x] >
'9'))
1459 ShowMessage(
"Track length value must be a positive whole number, or blank for no change");
1467 for(
int x = 1; x <= DistanceStr.Length(); x++)
1469 if((DistanceStr[x] <
'0') || (DistanceStr[x] >
'9'))
1471 ShowMessage(
"Distance must be a positive whole number");
1479 for(
int x = 1; x <= SpeedStr.Length(); x++)
1481 if((SpeedStr[x] <
'0') || (SpeedStr[x] >
'9'))
1483 ShowMessage(
"Speed limit must be a positive whole number, or blank for no change");
1491 for(
int x = 1; x <= SpeedStr.Length(); x++)
1493 if((SpeedStr[x] <
'0') || (SpeedStr[x] >
'9'))
1495 ShowMessage(
"Speed limit must be a positive whole number, or 'Mixed'");
1503 Dist = DistanceStr.ToInt();
1505 if(SpeedLimit != -1)
1507 SpeedLimit = SpeedStr.ToInt();
1516 if(((Dist != -1) && (Dist < 20)) || ((SpeedLimit != -1) && (SpeedLimit < 10)) || ((SpeedLimit != -1) && (SpeedLimit >
TTrain::MaximumSpeedLimit)))
1519 ShowMessage(
"Lengths must be 20m or more, and speeds must be between 10km/h and 400km/h");
1532 bool NamedLocPresent =
false;
1535 for(
int x = LowSelectHLoc; x < HighSelectHLoc; x++)
1537 for(
int y = LowSelectVLoc; y < HighSelectVLoc; y++)
1541 NamedLocPresent =
true;
1546 if(NamedLocPresent && (Dist < 50))
1548 ShowMessage(
"Note: Named location elements are quite short. If they are too short the simulation might depart too far from reality.");
1550 if(NamedLocPresent && (Dist > 200))
1552 ShowMessage(
"Note: Named location elements are quite long. If they are too long the simulation might depart too far from reality.");
1554 for(
int x = LowSelectHLoc; x < HighSelectHLoc; x++)
1556 for(
int y = LowSelectVLoc; y < HighSelectVLoc; y++)
1593 catch(
const Exception &e)
1616 catch(
const Exception &e)
1628 TMsgDlgButtons Buttons;
1629 Buttons << mbYes << mbNo;
1630 if(MessageDlg(
"This will reset the selected elements to default lengths & speed limits. Proceed?", mtWarning, Buttons, 0) == mrNo)
1649 for(
int x = LowSelectHLoc; x < HighSelectHLoc; x++)
1651 for(
int y = LowSelectVLoc; y < HighSelectVLoc; y++)
1705 throw Exception(
"Error, XLinkPos > 1 in SetOneDefaultTrackLength at " + AnsiString(TrackElement.
HLoc) +
" & " +
1706 AnsiString(TrackElement.
VLoc));
1722 catch(
const Exception &e)
1734 TMsgDlgButtons Buttons;
1735 Buttons << mbYes << mbNo;
1736 if(MessageDlg(
"This will reset ALL track elements to default lengths & speed limits. Proceed?", mtWarning, Buttons, 0) == mrNo)
1758 catch(
const Exception &e)
1786 bool GraphicFoundInVector =
false;
1787 for(TTrack::TUserGraphicVector::iterator UGVIt =
Track->
UserGraphicVector.begin(); UGVIt < Track->UserGraphicVector.end(); UGVIt++)
1789 if(UGMIt->first == UGVIt->FileName)
1791 GraphicFoundInVector =
true;
1795 if(!GraphicFoundInVector)
1797 delete UGMIt->second;
1813 catch(
const Exception &e)
1853 catch(
const Exception &e)
1892 catch(
const Exception &e)
1922 catch(
const Exception &e)
1948 catch(
const Exception &e)
1967 catch(
const Exception &e)
1982 ShowMessage(
"No preferred direction selection");
1986 Screen->Cursor = TCursor(-11);
1993 Screen->Cursor = TCursor(-2);
1996 catch(
const Exception &e)
2009 TMsgDlgButtons Buttons;
2010 Buttons << mbYes << mbNo;
2011 if(MessageDlg(
"Do you really want to clear all preferred directions?", mtWarning, Buttons, 0) == mrNo)
2027 catch(
const Exception &e)
2042 Screen->Cursor = TCursor(-11);
2051 Screen->Cursor = TCursor(-2);
2054 catch(
const Exception &e)
2072 catch(
const Exception &e)
2093 catch(
const Exception &e)
2118 catch(
const Exception &e)
2144 InfoPanel->Caption =
"PRE-START: Select AUTOMATIC SIGNAL ROUTE start signal, or left click points to change manually";
2148 InfoPanel->Caption =
"OPERATING: Select AUTOMATIC SIGNAL ROUTE start signal, or left click points to change manually";
2157 catch(
const Exception &e)
2184 InfoPanel->Caption =
"PRE-START: Select PREFERRED ROUTE start signal, or left click points to change manually";
2188 InfoPanel->Caption =
"OPERATING: Select PREFERRED ROUTE start signal, or left click points to change manually";
2197 catch(
const Exception &e)
2224 InfoPanel->Caption =
"PRE-START: Select PREFERRED ROUTE start signal, or left click points to change manually";
2228 InfoPanel->Caption =
"OPERATING: Select PREFERRED ROUTE start signal, or left click points to change manually";
2237 catch(
const Exception &e)
2270 InfoPanel->Caption =
"PRE-START: Select UNRESTRICTED ROUTE start location, or left click points to change manually";
2274 InfoPanel->Caption =
"OPERATING: Select UNRESTRICTED ROUTE start location, or left click points to change manually";
2283 catch(
const Exception &e)
2298 InfoPanel->Caption =
"ROUTE CANCELLING: Right click on truncate element, first element to cancel (anywhere else to skip)";
2305 catch(
const Exception &e)
2332 catch(
const Exception &e)
2347 UnicodeString MessageStr =
"Please note that the session will be lost if it hasn't been saved. Do you still wish to exit?";
2350 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
2389 catch(
const Exception &e)
2431 catch(
const Exception &e)
2444 Screen->Cursor = TCursor(-11);
2445 std::ifstream VecFile(LoadFileName.c_str());
2446 if(!(VecFile.fail()))
2451 bool GraphicsFollow =
false;
2470 TFont *TempFont =
new TFont;
2471 TempFont->Style.Clear();
2472 TempFont->Name =
"MS Sans Serif";
2473 TempFont->Size = 10;
2475 TempFont->Charset = (TFontCharset)(0);
2484 if((LeftExcess > 0) && (RightExcess > 0))
2488 else if((LeftExcess > 0) && (RightExcess <= 0))
2493 else if((LeftExcess <= 0) && (RightExcess > 0))
2505 if((TopExcess > 0) && (BotExcess > 0))
2509 else if((TopExcess > 0) && (BotExcess <= 0))
2514 else if((TopExcess <= 0) && (BotExcess > 0))
2531 if((LastChar ==
'y') || (LastChar ==
'Y'))
2535 ShowMessage(
"Railway not ready for operation so unable to load as a .rly file. Loading as a new railway under development");
2542 Screen->Cursor = TCursor(-2);
2576 ShowMessage(
"File open failed prior to load");
2578 Screen->Cursor = TCursor(-2);
2582 ShowMessage(
"File integrity check failed - unable to load");
2598 Screen->Cursor = TCursor(-11);
2600 if(!(VecFile.fail()))
2628 ShowMessage(
"File open failed prior to save");
2630 Screen->Cursor = TCursor(-2);
2635 catch(
const Exception &e)
2651 catch(
const Exception &e)
2668 ShowMessage(
"Failed to find folder " +
IMAGE_DIR_NAME +
" in the folder where 'railway.exe' resides. Image can't be saved");
2672 Screen->Cursor = TCursor(-11);
2675 AnsiString ImageFileName = TDateTime::CurrentDateTime().FormatString(
"dd-mm-yyyy hh.nn.ss");
2679 AnsiString ShortName =
"";
2680 for(
int x = ImageFileName.Length(); x > 0; x--)
2682 if(ImageFileName[x] ==
'\\')
2684 ShortName = ImageFileName.SubString(x + 1, ImageFileName.Length() - x - 4);
2688 ShowMessage(
"A bitmap file named " + ShortName +
" will be created in the Images folder");
2689 Graphics::TBitmap *RailwayImage =
new Graphics::TBitmap;
2690 RailwayImage->PixelFormat = pf8bit;
2696 RailwayImage->Width = HPosMax - HPosMin;
2697 RailwayImage->Height = VPosMax - VPosMin;
2705 int NewWidth = (TextPtr->HPos - HPosMin) + (abs(TextPtr->Font->Height) * TextPtr->TextString.Length() * 0.7);
2706 int NewHeight = (TextPtr->VPos - VPosMin) + (abs(TextPtr->Font->Height) * 1.5);
2707 if(NewWidth > RailwayImage->Width)
2709 RailwayImage->Width = NewWidth;
2711 if(NewHeight > RailwayImage->Height)
2713 RailwayImage->Height = NewHeight;
2717 RailwayImage->Canvas->Brush->Color =
clB5G5R5;
2718 TRect Rect(0, 0, RailwayImage->Width, RailwayImage->Height);
2719 RailwayImage->Canvas->FillRect(Rect);
2727 RailwayImage->SaveToFile(ImageFileName);
2728 delete RailwayImage;
2731 Screen->Cursor = TCursor(-2);
2734 catch(
const Exception &e)
2736 if(e.Message.Pos(
"torage") > 0)
2738 Screen->Cursor = TCursor(-2);
2739 UnicodeString MessageStr =
"Insufficient memory available to store this image";
2740 Application->MessageBox(MessageStr.c_str(), L
"", MB_OK | MB_ICONWARNING);
2760 ShowMessage(
"Failed to find folder " +
IMAGE_DIR_NAME +
" in the folder where 'railway.exe' resides. Image can't be saved");
2764 Screen->Cursor = TCursor(-11);
2767 AnsiString ImageFileName = TDateTime::CurrentDateTime().FormatString(
"dd-mm-yyyy hh.nn.ss");
2771 AnsiString ShortName =
"";
2772 for(
int x = ImageFileName.Length(); x > 0; x--)
2774 if(ImageFileName[x] ==
'\\')
2776 ShortName = ImageFileName.SubString(x + 1, ImageFileName.Length() - x - 4);
2780 ShowMessage(
"A bitmap file named " + ShortName +
" will be created in the Images folder");
2781 Graphics::TBitmap *RailwayImage =
new Graphics::TBitmap;
2782 RailwayImage->PixelFormat = pf8bit;
2787 RailwayImage->Width = HPosMax - HPosMin;
2788 RailwayImage->Height = VPosMax - VPosMin;
2796 int NewWidth = (TextPtr->HPos - HPosMin) + (abs(TextPtr->Font->Height) * TextPtr->TextString.Length() * 0.7);
2797 int NewHeight = (TextPtr->VPos - VPosMin) + (abs(TextPtr->Font->Height) * 1.5);
2798 if(NewWidth > RailwayImage->Width)
2800 RailwayImage->Width = NewWidth;
2802 if(NewHeight > RailwayImage->Height)
2804 RailwayImage->Height = NewHeight;
2808 RailwayImage->Canvas->Brush->Color =
clB5G5R5;
2809 TRect Rect(0, 0, RailwayImage->Width, RailwayImage->Height);
2810 RailwayImage->Canvas->FillRect(Rect);
2813 for(
int x = 0; x < ((RailwayImage->Width) / 16); x++)
2815 for(
int y = 0; y < ((RailwayImage->Height) / 16); y++)
2825 RailwayImage->SaveToFile(ImageFileName);
2826 delete RailwayImage;
2829 Screen->Cursor = TCursor(-2);
2832 catch(
const Exception &e)
2834 if(e.Message.Pos(
"torage") > 0)
2836 Screen->Cursor = TCursor(-2);
2837 UnicodeString MessageStr =
"Insufficient memory available to store this image";
2838 Application->MessageBox(MessageStr.c_str(), L
"", MB_OK | MB_ICONWARNING);
2857 ShowMessage(
"Failed to find folder " +
IMAGE_DIR_NAME +
" in the folder where 'railway.exe' resides. Image can't be saved");
2861 Screen->Cursor = TCursor(-11);
2864 AnsiString ImageFileName = TDateTime::CurrentDateTime().FormatString(
"dd-mm-yyyy hh.nn.ss");
2868 AnsiString ShortName =
"";
2869 for(
int x = ImageFileName.Length(); x > 0; x--)
2871 if(ImageFileName[x] ==
'\\')
2873 ShortName = ImageFileName.SubString(x + 1, ImageFileName.Length() - x - 4);
2877 ShowMessage(
"A bitmap file named " + ShortName +
" will be created in the Images folder");
2878 Graphics::TBitmap *RailwayImage =
new Graphics::TBitmap;
2879 RailwayImage->PixelFormat = pf8bit;
2884 RailwayImage->Width = HPosMax - HPosMin;
2885 RailwayImage->Height = VPosMax - VPosMin;
2893 int NewWidth = (TextPtr->HPos - HPosMin) + (abs(TextPtr->Font->Height) * TextPtr->TextString.Length() * 0.7);
2894 int NewHeight = (TextPtr->VPos - VPosMin) + (abs(TextPtr->Font->Height) * 1.5);
2895 if(NewWidth > RailwayImage->Width)
2897 RailwayImage->Width = NewWidth;
2899 if(NewHeight > RailwayImage->Height)
2901 RailwayImage->Height = NewHeight;
2905 RailwayImage->Canvas->Brush->Color =
clB5G5R5;
2906 TRect Rect(0, 0, RailwayImage->Width, RailwayImage->Height);
2907 RailwayImage->Canvas->FillRect(Rect);
2915 RailwayImage->SaveToFile(ImageFileName);
2916 delete RailwayImage;
2919 Screen->Cursor = TCursor(-2);
2922 catch(
const Exception &e)
2924 if(e.Message.Pos(
"torage") > 0)
2926 Screen->Cursor = TCursor(-2);
2927 UnicodeString MessageStr =
"Insufficient memory available to store this image";
2928 Application->MessageBox(MessageStr.c_str(), L
"", MB_OK | MB_ICONWARNING);
2947 ShowMessage(
"Failed to find folder " +
IMAGE_DIR_NAME +
" in the folder where 'railway.exe' resides. Image can't be saved");
2951 Screen->Cursor = TCursor(-11);
2956 TimetableTimeStr = TimetableTimeStr.SubString(1, 2) +
'.' + TimetableTimeStr.SubString(4, 2) +
'.' + TimetableTimeStr.SubString(7, 2);
2957 AnsiString ImageFileName = TDateTime::CurrentDateTime().FormatString(
"dd-mm-yyyy hh.nn.ss");
2962 AnsiString ShortName =
"";
2963 for(
int x = ImageFileName.Length(); x > 0; x--)
2965 if(ImageFileName[x] ==
'\\')
2967 ShortName = ImageFileName.SubString(x + 1, ImageFileName.Length() - x - 4);
2971 ShowMessage(
"A bitmap file named " + ShortName +
" will be created in the Images folder");
2972 Graphics::TBitmap *RailwayImage =
new Graphics::TBitmap;
2973 RailwayImage->PixelFormat = pf8bit;
2978 RailwayImage->Width = HPosMax - HPosMin;
2979 RailwayImage->Height = VPosMax - VPosMin;
2987 int NewWidth = (TextPtr->HPos - HPosMin) + (abs(TextPtr->Font->Height) * TextPtr->TextString.Length() * 0.7);
2988 int NewHeight = (TextPtr->VPos - VPosMin) + (abs(TextPtr->Font->Height) * 1.5);
2989 if(NewWidth > RailwayImage->Width)
2991 RailwayImage->Width = NewWidth;
2993 if(NewHeight > RailwayImage->Height)
2995 RailwayImage->Height = NewHeight;
2999 RailwayImage->Canvas->Brush->Color =
clB5G5R5;
3000 TRect Rect(0, 0, RailwayImage->Width, RailwayImage->Height);
3001 RailwayImage->Canvas->FillRect(Rect);
3016 bool BreakFlag =
false;
3042 RailwayImage->SaveToFile(ImageFileName);
3043 delete RailwayImage;
3046 Screen->Cursor = TCursor(-2);
3049 catch(
const Exception &e)
3051 if(e.Message.Pos(
"torage") > 0)
3053 Screen->Cursor = TCursor(-2);
3054 UnicodeString MessageStr =
"Insufficient memory available to store this image";
3055 Application->MessageBox(MessageStr.c_str(), L
"", MB_OK | MB_ICONWARNING);
3083 Screen->Cursor = TCursor(-11);
3085 if(!(VecFile.fail()))
3113 ShowMessage(
"Railway failed to save - can't open file");
3115 Screen->Cursor = TCursor(-2);
3119 catch(
const Exception &e)
3133 catch(
const Exception &e)
3155 catch(
const Exception &e)
3171 ShowMessage(
"Failed to find folder " +
FORMATTEDTT_DIR_NAME +
" in the folder where 'railway.exe' resides. Timetable can't be exported");
3179 Screen->Cursor = TCursor(-2);
3182 catch(
const Exception &e)
3242 AZOrderButton->Hint = AnsiString(
"Arrange services in alphabetical order Toggle with Shift+ Z");
3260 ActiveTrackElementNameMapEntry.first =
Track->
TrackVector.at(x).ActiveTrackElementName;
3261 ActiveTrackElementNameMapEntry.second = 0;
3311 catch(
const Exception &e)
3360 if(TTBLFile.is_open())
3364 while(!TTBLFile.eof())
3367 if((c < 32) && (c != 13) && (c != 10) && (c !=
'\0'))
3369 ShowMessage(
"Timetable file is empty or contains non-ascii characters, codes must be between 20 and 127, or CR or LF");
3379 ShowMessage(
"Failed to open timetable file, make sure it's not open in another application");
3386 if(TTBLFile.is_open())
3395 AZOrderButton->Hint = AnsiString(
"Arrange services in alphabetical order Toggle with Shift+ Z");
3408 char *TimetableEntryString =
new char[10000];
3411 TTBLFile.getline(TimetableEntryString, 10000,
'\0');
3412 if(TTBLFile.eof() && (TimetableEntryString[0] ==
'\0'))
3418 AnsiString OneLine(TimetableEntryString);
3422 delete[]TimetableEntryString;
3427 ShowMessage(
"Failed to open timetable file, make sure it's not open in another application");
3462 ActiveTrackElementNameMapEntry.first =
Track->
TrackVector.at(x).ActiveTrackElementName;
3463 ActiveTrackElementNameMapEntry.second = 0;
3488 catch(
const Exception &e)
3507 InfoPanel->Caption =
"Timetable mode: editor hidden";
3514 ShowHideTTButton->Hint =
"Hide the timetable editor to see the railway Shift H";
3519 catch(
const Exception &e)
3560 catch(
const Exception &e)
3601 catch(
const Exception &e)
3621 catch(
const Exception &e)
3634 bool ValidFlag =
true;
3655 TDateTime DummyTime;
3673 ShowMessage(
"One or more times excessive, not permitted to exceed 95 hours");
3677 AnsiString MinsStr = AnsiString(Mins), HrsStr = AnsiString(Hrs);
3680 MinsStr =
"0" + MinsStr;
3684 HrsStr =
"0" + HrsStr;
3688 NewString += HrsStr +
':' + MinsStr;
3705 catch(
const Exception &e)
3718 bool ValidFlag =
true;
3739 TDateTime DummyTime;
3757 ShowMessage(
"One or more times are now before 00:00, this is not permitted");
3761 AnsiString MinsStr = AnsiString(Mins), HrsStr = AnsiString(Hrs);
3764 MinsStr =
"0" + MinsStr;
3768 HrsStr =
"0" + HrsStr;
3772 NewString += HrsStr +
':' + MinsStr;
3788 catch(
const Exception &e)
3826 catch(
const Exception &e)
3871 if(OldVectorPos == 0)
3899 catch(
const Exception &e)
3958 catch(
const Exception &e)
3976 UnicodeString MessageStr =
"Are you sure this entry should be deleted?";
3977 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
4009 if(OldVectorPos == 0)
4037 catch(
const Exception &e)
4058 AnsiString TempStr =
"";
4059 bool ActiveLine =
false;
4084 while(TempStr[TempStr.Length()] ==
',')
4086 TempStr = TempStr.SubString(1, TempStr.Length() - 1);
4117 (*TTCurrentEntryPtr) = TempStr;
4187 catch(
const Exception &e)
4202 ShowMessage(
"Timetable is empty, can't save an empty timetable");
4206 std::ofstream TTBLFile;
4241 if(TTBLFile.is_open())
4245 TTBLFile << (*TEVPtr).c_str() <<
'\0';
4252 ShowMessage(
CreateEditTTFileName +
" failed to open, ensure not already open in another application");
4258 catch(
const Exception &e)
4273 ShowMessage(
"Timetable is empty, can't save an empty timetable");
4277 std::ofstream TTBLFile;
4286 for(
int x =
SaveTTDialog->FileName.Length(); x > 0; x--)
4304 if(TTBLFile.is_open())
4308 TTBLFile << (*TEVPtr).c_str() <<
'\0';
4315 ShowMessage(
CreateEditTTFileName +
" failed to open, ensure not already open in another application");
4321 catch(
const Exception &e)
4335 bool EndOfFile =
false;
4336 bool FinalCallFalse =
false;
4337 bool GiveMessagesTrue =
true;
4338 bool CheckLocationsExistInRailway =
false;
4341 CheckLocationsExistInRailway =
true;
4348 "The basic syntax seems OK but this check is very limited. Other aspects can only be checked by validating the whole timetable with the appropriate railway (.rly) loaded");
4354 catch(
const Exception &e)
4382 bool CheckLocationsExistInRailwayTrue =
true;
4385 Screen->Cursor = TCursor(-11);
4387 if(TTBLFile.is_open())
4391 ShowMessage(
"Timetable integrity OK");
4399 ShowMessage(
"Failed to open timetable file, make sure it's not open in another application");
4401 Screen->Cursor = TCursor(-2);
4411 catch(
const Exception &e)
4435 AnsiString TempStr = *
TEVPtr;
4473 catch(
const Exception &e)
4497 AnsiString TempStr = *
TEVPtr;
4535 catch(
const Exception &e)
4572 catch(
const Exception &e)
4587 UnicodeString MessageStr =
"All changes to the timetable will be lost - proceed?";
4588 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
4598 if(TTBLFile.is_open())
4615 char *TimetableEntryString =
new char[10000];
4618 TTBLFile.getline(TimetableEntryString, 10000,
'\0');
4619 if(TTBLFile.eof() && (TimetableEntryString[0] ==
'\0'))
4625 AnsiString OneLine(TimetableEntryString);
4629 delete[]TimetableEntryString;
4634 ShowMessage(
"Failed to open timetable file, make sure it's not open in another application");
4654 catch(
const Exception &e)
4669 ShowMessage(
"Failed to find folder " +
FORMATTEDTT_DIR_NAME +
" in the folder where 'railway.exe' resides. Timetable can't be exported");
4688 Screen->Cursor = TCursor(-2);
4693 catch(
const Exception &e)
4726 catch(
const Exception &e)
4741 UnicodeString MessageStr =
"The timetable has changed.\n\nAre you sure you want to exit without saving it?";
4742 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
4758 catch(
const Exception &e)
4786 catch(
const Exception &e)
4811 catch(
const Exception &e)
4829 catch(
const Exception &e)
4852 catch(
const Exception &e)
4904 catch(
const Exception &e)
4917 TrainController->
LogEvent(
"OAListBoxMouseUp," + AnsiString(X) +
"," + AnsiString(Y) +
"," + AnsiString(Button));
4929 int HPos, VPos, TrainID = -1, TrackVectorPosition = -1;
4936 if(Button == mbLeft)
4951 TPoint MainScreenPoint(ScreenPosH + 8, ScreenPosV + 8);
4952 TPoint CursPos =
MainScreen->ClientToScreen(MainScreenPoint);
4953 Mouse->CursorPos = CursPos;
4961 catch(
const Exception &e)
4975 if(Button == mbRight)
4981 catch(
const Exception &e)
4997 if((TopPos + (Y / 13)) >=
OAListBox->Items->Count)
5005 std::advance(OACurrentEntryPtr, ((Y / 13) + TopPos));
5007 int TrainIDorTVPos = OACurrentEntryPtr->second.second;
5008 if(TrainIDorTVPos >= 0)
5014 TrainID = TrainIDorTVPos;
5025 TrackVectorPosition = -(TrainIDorTVPos + 1);
5037 PreStartTime, ActiveSegment, PostEnd
5051 Segment = PreStartTime;
5054 if(Segment == PreStartTime)
5061 Segment = ActiveSegment;
5072 AnsiString CurrentStr = *
TEVPtr;
5073 if(CurrentStr !=
"")
5075 CurrentStr = CurrentStr.SubString(1, 10);
5076 for(
int x = 1; x < CurrentStr.Length(); x++)
5078 if((CurrentStr[x] < 32) || (CurrentStr[1] > 126))
5080 CurrentStr = CurrentStr.SubString(1, (x - 1));
5089 if(Segment == ActiveSegment)
5104 AnsiString Entry = *
TEVPtr;
5111 int SCPos = Entry.Pos(
';');
5112 int CPos = Entry.Pos(
',');
5119 if((CPos == 0) && (SCPos == 0))
5121 Entry = Entry.SubString(1, 12);
5123 else if((CPos > 0) && (SCPos > 0) && (CPos < SCPos))
5125 Entry = Entry.SubString(1, CPos - 1);
5127 else if((CPos > 0) && (SCPos > 0) && (CPos > SCPos))
5129 Entry = Entry.SubString(1, SCPos - 1);
5131 else if((CPos > 0) && (SCPos == 0))
5133 Entry = Entry.SubString(1, CPos - 1);
5137 Entry = Entry.SubString(1, SCPos - 1);
5150 if(Segment == PostEnd)
5158 AnsiString CurrentStr = *
TEVPtr;
5159 if(CurrentStr !=
"")
5161 CurrentStr = CurrentStr.SubString(1, 10);
5162 for(
int x = 1; x < CurrentStr.Length(); x++)
5164 if((CurrentStr[x] < 32) || (CurrentStr[1] > 126))
5166 CurrentStr = CurrentStr.SubString(1, (x - 1));
5197 UnicodeString MessageStr =
5198 "If you wish to preserve the original order don't save any changes whilst in alphabetical order.\n\n" "To preserve the original order use alphabetical order to find the service required, click it to display it,"
5199 " then revert to the original order where the same service will be displayed and can be changed.";
5200 Application->MessageBox(MessageStr.c_str(), L
"Please Note:", MB_OK | MB_ICONWARNING);
5213 std::sort(SortStart, SortEnd);
5215 bool CurrentEntryChanged =
false;
5221 CurrentEntryChanged =
true;
5224 if(!CurrentEntryChanged)
5229 AZOrderButton->Hint = AnsiString(
"Arrange services in original order Toggle with Shift+ Z");
5235 UnicodeString MessageStr =
5236 "Reverting to the original order will discard any changes made whilst in alphabetical order.\n\nTo preserve the changes click 'No', then save the timetable or use 'save as' if you wish to keep the original timetable.\n\nDo you wish to proceed?";
5237 int button = Application->MessageBox(MessageStr.c_str(), L
"Warning!", MB_YESNO | MB_ICONWARNING);
5251 bool CurrentEntryChanged =
false;
5257 CurrentEntryChanged =
true;
5260 if(!CurrentEntryChanged)
5265 AZOrderButton->Hint = AnsiString(
"Arrange services in alphabetical order Toggle with Shift+ Z");
5274 catch(
const Exception &e)
5285 AnsiString OutStr =
"";
5288 while(x < ConvStr.Length())
5290 if((ConvStr[x] ==
'\r') && (ConvStr[x + 1] ==
'\n'))
5298 OutStr += ConvStr[x];
5302 if(x == ConvStr.Length())
5304 OutStr += ConvStr[x];
5310 while(OutStr[OutStr.Length()] ==
',')
5312 OutStr = OutStr.SubString(1, OutStr.Length() - 1);
5386 InfoPanel->Caption =
"Select option or change entry";
5400 bool ValidFlag =
true;
5401 for(
int x = 1; x <= AnsiAddSubText.Length(); x++)
5403 if((AnsiAddSubText[x] >
'9') || (AnsiAddSubText[x] <
'0'))
5411 if(AnsiAddSubText.ToInt() != 0)
5484 bool ServiceEntry =
true;
5489 bool ServiceEntry =
false;
5501 InfoPanel->Caption =
"Add or change entry then save it, or cancel";
5511 AnsiString((
short)ServiceEntry));
5518 int CommaPos = Data.Pos(
',');
5519 if((CommaPos == 0) && (Data !=
""))
5521 CommaPos = Data.Length() + 1;
5524 if(Data.Length() <= CommaPos)
5528 Data = Data.SubString(CommaPos + 1, Data.Length() - CommaPos);
5567 if(CurrentStr !=
"")
5569 for(
int x = 1; x < CurrentStr.Length(); x++)
5571 if((CurrentStr[x] < 32) || (CurrentStr[1] > 126))
5573 CurrentStr = CurrentStr.SubString(1, (x - 1));
5606 TDateTime DummyTime;
5607 bool TimesPresent =
false;
5615 TimesPresent =
true;
5624 return(TimesPresent);
5638 UnicodeString MessageStr =
5639 "Note that leaving the track unlinked will cause preferred directions to be lost on reloading. Prevent by linking the track then resaving. Do you still wish to exit?";
5640 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
5649 UnicodeString MessageStr =
"The railway has changed, exit without saving?";
5650 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
5662 Application->Terminate();
5664 catch(
const Exception &e)
5687 catch(
const Exception &e)
5710 catch(
const Exception &e)
5733 catch(
const Exception &e)
5810 catch(
const Exception &e)
5828 catch(
const Exception &e)
5847 catch(
const Exception &e)
5886 catch(
const Exception &e)
5897 TrainController->
LogEvent(
"MainScreenMouseDown2," + AnsiString(Button) +
"," + AnsiString(X) +
"," + AnsiString(Y));
5899 "," + AnsiString(Y));
5910 int NoOffsetX, NoOffsetY;
5912 if(Button == mbRight)
5916 AnsiString Text =
"";
5923 Screen->Cursor = TCursor(-22);
5979 bool TrackEraseSuccessfulFlag;
5980 int ErasedTrackVectorPosition;
5981 Screen->Cursor = TCursor(-11);
5983 if(TrackEraseSuccessfulFlag)
5985 if(ErasedTrackVectorPosition > -1)
6018 Screen->Cursor = TCursor(-2);
6026 bool LeadingPointsAtLastElement =
false;
6041 if(!LeadingPointsAtLastElement)
6046 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Continue or set values (overall length), or right click to cancel/truncate";
6065 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Can't end on leading points, continue or truncate";
6143 if((TrainID01 > -1) && (TrainID23 > -1))
6193 AnsiString LocName =
"";
6198 if((LocName ==
"") && (Train.
MidElement > -1))
6320 Screen->Cursor = TCursor(-11);
6331 Screen->Cursor = TCursor(-2);
6406 Screen->Cursor = TCursor(-11);
6408 bool TrackLinkingRequiredFlag;
6410 TSpeedButton *TempSpeedButton = 0;
6420 bool InternalChecks =
true;
6428 if(TrackLinkingRequiredFlag)
6457 Screen->Cursor = TCursor(-2);
6471 NewGI.
Width = UGMIt->second->Width;
6472 NewGI.
Height = UGMIt->second->Height;
6498 AnsiString NameString;
6508 unsigned int ValidPosition;
6519 ValidElement = InactiveTrackElement1;
6520 ValidPosition = InactivePair.first;
6525 ValidElement = InactiveTrackElement2;
6526 ValidPosition = InactivePair.second;
6537 InfoPanel->Caption =
"NAMING LOCATIONS: Enter name, 'Carriage Return' to accept, 'Escape' to quit";
6568 bool FinishElement =
false, LeadingPointsAtLastElement =
false;
6569 Screen->Cursor = TCursor(-11);
6584 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Set values (overall length), or right click to cancel/truncate";
6598 Screen->Cursor = TCursor(-2);
6604 if(!LeadingPointsAtLastElement)
6609 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Continue or set values (overall length), or right click to cancel/truncate";
6630 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Can't end on leading points, need to continue or truncate";
6645 Screen->Cursor = TCursor(-2);
6650 Screen->Cursor = TCursor(-2);
6668 InfoPanel->Caption =
"CONNECTING GAPS: Connecting element selected";
6680 ShowMessage(
"All gaps set");
6708 int TrueX = 0, TrueY = 0;
6709 AnsiString ExistingText =
"";
6711 TFont *ExistingTextFont =
new TFont;
6712 int ExistingTextHPos = 0, ExistingTextVPos = 0;
6718 if((TrueX >= TextPtr->HPos) && (TrueX < (TextPtr->HPos + abs(TextPtr->Font->Height))) && (TrueY >= TextPtr->VPos) && (TrueY <
6719 (TextPtr->VPos + abs(TextPtr->Font->Height))))
6721 ExistingText = TextPtr->TextString;
6722 ExistingTextFont->Assign(TextPtr->Font);
6723 ExistingTextHPos = TextPtr->HPos;
6724 ExistingTextVPos = TextPtr->VPos;
6737 TextBox->Font->Assign(ExistingTextFont);
6739 Text_X = ExistingTextHPos;
6740 Text_Y = ExistingTextVPos;
6758 TextBox->Text =
"New Text: CR=end, ESC=quit";
6762 delete ExistingTextFont;
6864 Screen->Cursor = TCursor(-11);
6875 ShowMessage(
"Preferred direction added");
6879 Screen->Cursor = TCursor(-2);
6898 Screen->Cursor = TCursor(-2);
6902 Screen->Cursor = TCursor(-2);
6999 AnsiString(PDE.
VLoc));
7013 bool PointsChanged =
false;
7014 IDInt ReqPosRouteID(-1);
7016 bool CallonTrue =
true;
7024 ReqPosRouteID, PointsChanged))
7066 float TempSpeedVal = 1;
7136 int DivergingPosition = TrackElement.
Conn[3];
7138 DivergingPosition)))
7167 bool TrainPresent =
false;
7171 int BDVectorPos = -1;
7181 TDateTime TempExcessLCDownTime;
7192 if(TempExcessLCDownTime > TDateTime(0))
7222 AnsiString Message =
7223 AnsiString(
"This will open the level crossing manually (it will show in green).\n\nA manually opened"
7224 " level crossing must be manually closed, and as soon as possible to avoid time penalties.\n\n" "This message will not be shown again."
7269 InfoPanel->Caption =
"PRE-START: Select next route location";
7273 InfoPanel->Caption =
"OPERATING: Select next route location";
7286 bool CallonFalse =
false;
7294 InfoPanel->Caption =
"PRE-START: Select next route location";
7298 InfoPanel->Caption =
"OPERATING: Select next route location";
7320 Screen->Cursor = TCursor(-11);
7322 bool PointsChanged =
false;
7332 float TempSpeedVal = 1;
7341 else if(PointsChanged)
7356 Screen->Cursor = TCursor(-2);
7364 bool CallonFalse =
false;
7369 float TempSpeedVal = 1;
7378 else if(PointsChanged)
7396 Screen->Cursor = TCursor(-2);
7404 catch(
const Exception &e)
7418 TrainController->
LogEvent(
"MainScreenMouseDown3," + AnsiString(Button) +
"," + AnsiString(X) +
"," + AnsiString(Y));
7420 "," + AnsiString(Y));
7421 if(Button != mbLeft)
7427 Screen->Cursor = TCursor(-22);
7433 int HRounding, VRounding;
7506 else if(TempLevel2OperMode ==
Operating)
7509 OperateButton->Glyph->LoadFromResourceName(0,
"PauseGraphic");
7513 else if(TempLevel2OperMode ==
Paused)
7516 OperateButton->Glyph->LoadFromResourceName(0,
"RunGraphic");
7522 else if(TempLevel2OperMode ==
PreStart)
7525 OperateButton->Glyph->LoadFromResourceName(0,
"RunGraphic");
7536 catch(
const Exception &e)
7633 if(CurrentHLoc >= StartHLoc)
7641 if(CurrentVLoc >= StartVLoc)
7665 TRect TempRect(StartHLoc, StartVLoc, CurrentHLoc, CurrentVLoc);
7679 if(CurrentHLoc >= StartHLoc)
7687 if(CurrentVLoc >= StartVLoc)
7711 TRect TempRect(StartHLoc, StartVLoc, CurrentHLoc, CurrentVLoc);
7778 catch(
const Exception &e)
7814 TrainController->
LogEvent(
"MainScreenMouseUp," + AnsiString(Button) +
"," + AnsiString(X) +
"," + AnsiString(Y));
7817 Screen->Cursor = TCursor(-2);
7821 Screen->Cursor = TCursor(-11);
7826 if(EndHLoc >= StartHLoc)
7834 if(EndVLoc >= StartVLoc)
7842 if(StartHLoc >= EndHLoc)
7852 if(StartVLoc >= EndVLoc)
7889 Screen->Cursor = TCursor(-2);
7959 if(IATVecPair.second != IATVecPair.first)
7978 if((TextPtr->HPos >= LowSelectHPos) && (TextPtr->HPos < HighSelectHPos) && (TextPtr->VPos >= LowSelectVPos) && (TextPtr->VPos <
7986 bool SelectVectorNamedElement =
false;
7987 AnsiString SelectTextString;
7992 SelectVectorNamedElement =
true;
7996 if(SelectVectorNamedElement)
7998 SelectTextString =
"##**" + TextPtr->TextString;
8002 SelectTextString = TextPtr->TextString;
8004 TTextItem TextItem(TextPtr->HPos, TextPtr->VPos, SelectTextString, TextPtr->Font);
8013 for(TTrack::TUserGraphicVector::iterator UserGraphicPtr =
Track->
UserGraphicVector.begin(); UserGraphicPtr < Track->UserGraphicVector.end();
8016 if((UserGraphicPtr->HPos >= LowSelectHPos) && ((UserGraphicPtr->HPos + UserGraphicPtr->Width) < HighSelectHPos) &&
8017 (UserGraphicPtr->VPos >= LowSelectVPos) && ((UserGraphicPtr->VPos + UserGraphicPtr->Height) < HighSelectVPos))
8030 Screen->Cursor = TCursor(-2);
8036 Screen->Cursor = TCursor(-11);
8042 if(EndHLoc >= StartHLoc)
8050 if(EndVLoc >= StartVLoc)
8058 if(StartHLoc >= EndHLoc)
8068 if(StartVLoc >= EndVLoc)
8101 Screen->Cursor = TCursor(-2);
8132 Screen->Cursor = TCursor(-2);
8157 catch(
const Exception &e)
8195 throw Exception(
"Warning - Utilities->CallLog contains more than 50 items");
8220 catch(
const Exception &e)
8316 if(
WholeRailwayMoving && (GetAsyncKeyState(VK_LBUTTON) >= 0) && (GetAsyncKeyState(VK_RBUTTON) >= 0))
8319 Screen->Cursor = TCursor(-2);
8344 bool TrainPresent =
false;
8361 TDateTime TempExcessLCDownTime;
8370 if(TempExcessLCDownTime > TDateTime(0))
8399 bool ElementRemovedFlag =
false;
8416 int RouteNumber1, RouteNumber2, TrainID;
8424 ElementRemovedFlag =
true;
8440 bool WH1 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog1->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog1->Width +
OutputLog1->Left))
8443 bool WH2 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog2->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog2->Width +
OutputLog2->Left))
8446 bool WH3 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog3->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog3->Width +
OutputLog3->Left))
8449 bool WH4 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog4->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog4->Width +
OutputLog4->Left))
8452 bool WH5 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog5->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog5->Width +
OutputLog5->Left))
8455 bool WH6 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog6->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog6->Width +
OutputLog6->Left))
8458 bool WH7 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog7->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog7->Width +
OutputLog7->Left))
8461 bool WH8 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog8->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog8->Width +
OutputLog8->Left))
8464 bool WH9 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog9->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog9->Width +
OutputLog9->Left))
8467 bool WH10 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog10->Left) &&
8471 if(WH1 || WH2 || WH3 || WH4 || WH5 || WH6 || WH7 || WH8 || WH9 || WH10)
8491 AnsiString Type[15] =
8493 "Simple",
"Crossover",
"Points",
"Buffers",
"Bridge",
"SignalPost",
"Continuation",
"Platform",
"GapJump",
"FootCrossing",
"Unused",
"Concourse",
8494 "Parapet",
"NamedNonStationLocation",
"Erase"
8497 int ScreenX = Mouse->CursorPos.x -
MainScreen->ClientOrigin.x;
8498 int ScreenY = Mouse->CursorPos.y -
MainScreen->ClientOrigin.y;
8500 AnsiString MouseStr =
"Posx: " + AnsiString(ScreenX) +
"; Posy: " + AnsiString(ScreenY);
8505 DevelopmentPanel->Caption = MouseStr +
"; TVPos: " + AnsiString(Position) +
"; H: " + AnsiString(HLoc) +
"; V: " + AnsiString(VLoc) +
8506 "; SpTg: " + AnsiString(TrackElement.
SpeedTag) +
"; Type: " + Type[TrackElement.
TrackType] +
"; Att: " + AnsiString(TrackElement.
Attribute)
8523 if((GetKeyState(VK_LBUTTON) >= 0) && (GetKeyState(VK_RBUTTON) >= 0) && (
TTCurrentEntryPtr > 0))
8653 Screen->Cursor = TCursor(-11);
8805 int RouteStartVecPos;
8821 if(FoundFlag && (RouteStartVecPos > -1))
8837 catch(
const Exception &e)
8855 InfoPanel->Caption =
"CALLING ON: Select signal for call on";
8869 catch(
const Exception &e)
8883 Screen->Cursor = TCursor(-11);
8927 Screen->Cursor = TCursor(-2);
8930 catch(
const Exception &e)
8944 Screen->Cursor = TCursor(-11);
8988 Screen->Cursor = TCursor(-2);
8991 catch(
const Exception &e)
9005 Screen->Cursor = TCursor(-11);
9050 Screen->Cursor = TCursor(-2);
9053 catch(
const Exception &e)
9067 Screen->Cursor = TCursor(-11);
9111 Screen->Cursor = TCursor(-2);
9114 catch(
const Exception &e)
9128 Screen->Cursor = TCursor(-11);
9169 OperateButton->Glyph->LoadFromResourceName(0,
"PauseGraphic");
9176 OperateButton->Glyph->LoadFromResourceName(0,
"RunGraphic");
9185 OperateButton->Glyph->LoadFromResourceName(0,
"RunGraphic");
9212 if((LeftExcess > 0) && (RightExcess > 0))
9216 else if((LeftExcess > 0) && (RightExcess <= 0))
9221 else if((LeftExcess <= 0) && (RightExcess > 0))
9233 if((TopExcess > 0) && (BotExcess > 0))
9237 else if((TopExcess > 0) && (BotExcess <= 0))
9242 else if((TopExcess <= 0) && (BotExcess > 0))
9258 ZoomButton->Glyph->LoadFromResourceName(0,
"ZoomIn");
9260 Screen->Cursor = TCursor(-2);
9264 catch(
const Exception &e)
9278 Screen->Cursor = TCursor(-11);
9303 Screen->Cursor = TCursor(-2);
9307 catch(
const Exception &e)
9335 catch(
const Exception &e)
9351 catch(
const Exception &e)
9372 ShowMessage(
"Please be aware when pasting that anything inside the pasted area will be overwritten.\n\nThis warning will not be shown again.");
9383 catch(
const Exception &e)
9405 TRect NewSelectRect(TLHCH, TLHCV, BRHCH, BRHCV);
9442 catch(
const Exception &e)
9463 catch(
const Exception &e)
9484 catch(
const Exception &e)
9532 int MidVPosAfterFlip = ((VerSum * 16) + 15) - MidVPosBeforeFlip;
9540 catch(
const Exception &e)
9588 int MidHPosAfterMirror = ((HorSum * 16) + 15) - MidHPosBeforeMirror;
9590 if(LeftPosAfterMirror < (
SelectRect.left * 16))
9600 catch(
const Exception &e)
9653 int MidVPosAfterFlip = ((VerSum * 16) + 15) - MidVPosBeforeFlip;
9665 int MidHPosAfterMirror = ((HorSum * 16) + 15) - MidHPosBeforeMirror;
9667 if(LeftPosAfterMirror < (
SelectRect.left * 16))
9679 catch(
const Exception &e)
9692 Screen->Cursor = TCursor(-11);
9709 int button = Application->MessageBox
9710 (L
"Original selection adjusted to make it square. 'OK' to keep this selection or 'Cancel' to make a new selection",
9711 L
"Left click and hold here to move this message box", MB_OKCANCEL);
9712 if(button == IDCANCEL)
9720 Screen->Cursor = TCursor(-2);
9759 if(IATVecPair.second != IATVecPair.first)
9777 if((TextPtr->HPos >= LowSelectHPos) && (TextPtr->HPos < HighSelectHPos) && (TextPtr->VPos >= LowSelectVPos) && (TextPtr->VPos < HighSelectVPos))
9784 bool SelectVectorNamedElement =
false;
9785 AnsiString SelectTextString;
9790 SelectVectorNamedElement =
true;
9794 if(SelectVectorNamedElement)
9796 SelectTextString =
"##**" + TextPtr->TextString;
9800 SelectTextString = TextPtr->TextString;
9802 TTextItem TextItem(TextPtr->HPos, TextPtr->VPos, SelectTextString, TextPtr->Font);
9811 for(TTrack::TUserGraphicVector::iterator UserGraphicPtr =
Track->
UserGraphicVector.begin(); UserGraphicPtr < Track->UserGraphicVector.end();
9814 if((UserGraphicPtr->HPos >= LowSelectHPos) && ((UserGraphicPtr->HPos + UserGraphicPtr->Width) < HighSelectHPos) && (UserGraphicPtr->VPos >=
9815 LowSelectVPos) && ((UserGraphicPtr->VPos + UserGraphicPtr->Height) < HighSelectVPos))
9854 int MidHPosAfterRotate = ((
SelectRect.bottom * 16) - 1) + (
SelectRect.left * 16) - MidVPosBeforeRotate;
9861 Screen->Cursor = TCursor(-2);
9866 catch(
const Exception &e)
9880 Screen->Cursor = TCursor(-11);
9897 int button = Application->MessageBox
9898 (L
"Original selection adjusted to make it square. 'OK' to keep this selection or 'Cancel' to make a new selection",
9899 L
"Left click and hold here to move this message box", MB_OKCANCEL);
9900 if(button == IDCANCEL)
9908 Screen->Cursor = TCursor(-2);
9947 if(IATVecPair.second != IATVecPair.first)
9965 if((TextPtr->HPos >= LowSelectHPos) && (TextPtr->HPos < HighSelectHPos) && (TextPtr->VPos >= LowSelectVPos) && (TextPtr->VPos < HighSelectVPos))
9972 bool SelectVectorNamedElement =
false;
9973 AnsiString SelectTextString;
9978 SelectVectorNamedElement =
true;
9982 if(SelectVectorNamedElement)
9984 SelectTextString =
"##**" + TextPtr->TextString;
9988 SelectTextString = TextPtr->TextString;
9990 TTextItem TextItem(TextPtr->HPos, TextPtr->VPos, SelectTextString, TextPtr->Font);
9999 for(TTrack::TUserGraphicVector::iterator UserGraphicPtr =
Track->
UserGraphicVector.begin(); UserGraphicPtr < Track->UserGraphicVector.end();
10002 if((UserGraphicPtr->HPos >= LowSelectHPos) && ((UserGraphicPtr->HPos + UserGraphicPtr->Width) < HighSelectHPos) && (UserGraphicPtr->VPos >=
10003 LowSelectVPos) && ((UserGraphicPtr->VPos + UserGraphicPtr->Height) < HighSelectVPos))
10043 int MidVPosAfterRotate = ((
SelectRect.bottom * 16) - 1) + (
SelectRect.left * 16) - MidHPosBeforeRotate;
10049 Screen->Cursor = TCursor(-2);
10054 catch(
const Exception &e)
10074 catch(
const Exception &e)
10093 catch(
const Exception &e)
10111 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Set values or leave blank for no change";
10114 ShowMessage(
"Note: length value will apply to each element's track within the selection.\n\nThis message will not be shown again.");
10124 catch(
const Exception &e)
10142 bool FoundFlag =
false;
10186 catch(
const Exception &e)
10217 Clipboard()->Clear();
10218 Clipboard()->Close();
10221 catch(
const EClipboardException &e)
10225 catch(
const Exception &e)
10257 bool CheckLocationsExistInRailwayTrue =
true;
10261 Screen->Cursor = TCursor(-11);
10262 std::ifstream TTBLFile(AnsiString(
TimetableDialog->FileName).c_str(), std::ios_base::binary);
10263 if(TTBLFile.is_open())
10265 bool SessionFileFalse =
false;
10274 ShowMessage(
"Failed to open timetable file, make sure it's not open in another application");
10276 Screen->Cursor = TCursor(-2);
10280 ShowMessage(
"Timetable preliminary integrity check failed - unable to load");
10287 catch(
const Exception &e)
10314 AnsiString LocName =
"";
10319 if((LocName ==
"") && (Train.
MidElement > -1))
10337 if((NextElementPosition > -1) && (NextEntryPos > -1))
10353 if((LocName ==
"") && (Train.
MidElement > -1))
10360 catch(
const Exception &e)
10384 AnsiString LocName =
"";
10389 if((LocName ==
"") && (Train.
MidElement > -1))
10397 if((LocName ==
"") && (Train.
MidElement > -1))
10431 int NextElementPos = -1;
10432 int NextEntryPos = -1;
10451 if((NextElementPos > -1) && (NextEntryPos > -1))
10485 catch(
const Exception &e)
10503 AnsiString LocName =
"";
10508 if((LocName ==
"") && (Train.
MidElement > -1))
10516 if((LocName ==
"") && (Train.
MidElement > -1))
10523 catch(
const Exception &e)
10553 int NextElementPos = -1;
10554 int NextEntryPos = -1;
10562 if((NextElementPos > -1) && (NextEntryPos > -1))
10582 catch(
const Exception &e)
10596 TTrain *TrainToBeJoinedBy;
10609 ShowMessage(
"Can't join two trains when both are without power");
10613 AnsiString TrainToBeJoinedByHeadCode = TrainToBeJoinedBy->
HeadCode;
10615 double OtherBrakeForce = TrainToBeJoinedBy->
MaxBrakeRate * TrainToBeJoinedBy->
Mass;
10617 double CombinedBrakeRate = (OtherBrakeForce + OwnBrakeForce) / (TrainToBeJoinedBy->
Mass + ThisTrain.
Mass);
10618 ThisTrain.
Mass += TrainToBeJoinedBy->
Mass;
10625 AnsiString LocName =
"";
10630 if((LocName ==
"") && (ThisTrain.
MidElement > -1))
10634 if((LocName ==
"") && ThisTrain.
LeadElement > -1)
10638 if((LocName ==
"") && (ThisTrain.
MidElement > -1))
10672 catch(
const Exception &e)
10703 AnsiString LocName =
"";
10708 if((LocName ==
"") && (Train.
MidElement > -1))
10716 if((LocName ==
"") && (Train.
MidElement > -1))
10732 catch(
const Exception &e)
10767 catch(
const Exception &e)
10783 if(NextElementPos < 0)
10785 throw Exception(
"Error, no element in front in PassRedSignalMenuItemClick");
10796 throw Exception(
"Error, next element not a signal type in PassRedSignalMenuItemClick");
10810 catch(
const Exception &e)
10836 int NextElementPos = -1;
10838 int NextEntryPos = -1;
10846 if((NextElementPos > -1) && (NextEntryPos > -1))
10856 catch(
const Exception &e)
10875 UnicodeString Message = UnicodeString(Train.
HeadCode) +
" will be removed from the railway - proceed?";
10876 int button = Application->MessageBox(Message.c_str(), L
"Please confirm", MB_YESNO);
10889 AnsiString LocName =
"";
10894 if((LocName ==
"") && (Train.
MidElement > -1))
10902 if((LocName ==
"") && (Train.
MidElement > -1))
10949 int FirstRouteElementVecPos = LeadTrackElement.
Conn[Train.
LeadExitPos];
10959 bool FirstPass =
true;
10966 if(FirstPass && (TVPos2 != FirstRouteElementVecPos))
11045 catch(
const Exception &e)
11060 Application->Terminate();
11074 catch(
const Exception &e)
11088 UnicodeString MessageStr =
11089 "Note that leaving the track unlinked will cause preferred directions to be lost on reloading. Prevent by linking the track then resaving. Do you still wish to exit?";
11090 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
11100 UnicodeString MessStr =
"";
11103 MessStr = UnicodeString(
"The railway and the timetable have both changed, exit without saving either?");
11107 MessStr = UnicodeString(
"The railway has changed, exit without saving?");
11111 MessStr = UnicodeString(
"The timetable has changed, exit without saving?");
11113 int button = Application->MessageBox(MessStr.c_str(), L
"Please confirm", MB_YESNO);
11125 UnicodeString MessageStr =
"Please note that the session will be lost if it hasn't been saved. Do you still wish to exit?";
11128 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
11147 catch(
const Exception &e)
11161 if((Shift.Contains(ssAlt)) && (Shift.Contains(ssCtrl)))
11174 else if(Key ==
'3')
11186 else if(Key ==
'4')
11190 else if(Key ==
'5')
11192 TMsgDlgButtons Buttons;
11193 Buttons << mbYes << mbNo;
11194 if(MessageDlg(
"Do you wish to allow facing signals next to bridges? If so please be aware that routes cannot be truncated to these signals.",
11195 mtWarning, Buttons, 0) == mrYes)
11205 else if(Shift.Contains(ssCtrl) && !Shift.Contains(ssShift) && !Shift.Contains(ssAlt))
11209 else if(Shift.Contains(ssShift) && !Shift.Contains(ssCtrl) && !Shift.Contains(ssAlt))
11221 if((Key != VK_SHIFT) && (Key != VK_CONTROL))
11239 else if(Key == VK_DOWN)
11246 else if(Key == VK_LEFT)
11253 else if(Key == VK_RIGHT)
11260 else if(Key == VK_HOME)
11268 else if(Key == VK_END)
11275 else if(Key == VK_END)
11290 if(Shift.Contains(ssShift) && !Shift.Contains(ssAlt) && !Shift.Contains(ssCtrl) &&
NewHomeButton->Enabled &&
NewHomeButton->Visible)
11301 if(!Shift.Contains(ssCtrl))
11365 if(Key ==
'S' || Key ==
's')
11376 if(Shift.Contains(ssShift))
11391 if(Shift.Contains(ssShift) && !Shift.Contains(ssCtrl) && !Shift.Contains(ssAlt))
11438 if(Shift.Contains(ssCtrl) && !Shift.Contains(ssShift) && !Shift.Contains(ssAlt))
11444 if(Key ==
'S' || Key ==
's')
11450 if(!Shift.Contains(ssCtrl) && !Shift.Contains(ssShift) && !Shift.Contains(ssAlt))
11461 if(!Shift.Contains(ssShift) && !Shift.Contains(ssCtrl))
11468 if(!Shift.Contains(ssShift) && Shift.Contains(ssCtrl))
11474 if(Key ==
'S' || Key ==
's')
11480 if(Shift.Contains(ssShift) && !Shift.Contains(ssCtrl))
11501 if(!Shift.Contains(ssShift) && !Shift.Contains(ssCtrl))
11508 if(Shift.Contains(ssShift) && !Shift.Contains(ssCtrl))
11514 if(Key ==
'S' || Key ==
's')
11519 else if(Key ==
'H' || Key ==
'h')
11532 if(Shift.Contains(ssShift) && !Shift.Contains(ssCtrl))
11603 if(
SaveTTButton->Enabled && (Key ==
'T' || Key ==
't'))
11626 if(
FloatingInfoMenu->Enabled && !Shift.Contains(ssAlt) && Shift.Contains(ssCtrl) && Shift.Contains(ssShift))
11628 if(Key ==
'I' || Key ==
'i')
11634 if(Key ==
'S' || Key ==
's')
11638 else if(Key ==
'T' || Key ==
't')
11647 catch(
const Exception &e)
11657 if((Key != VK_SHIFT) && (Key != VK_CONTROL))
11779 catch(
const Exception &e)
11792 Application->HelpKeyword(u
"Introduction");
11794 catch(
const Exception &e)
11804 const UnicodeString Link =
"http://www.railwayoperationsimulator.com";
11805 ::ShellExecute(Handle, NULL, (Link).c_str(), NULL, NULL, SW_SHOWNORMAL);
11828 catch(
const Exception &e)
11854 catch(
const Exception &e)
11880 catch(
const Exception &e)
11936 bool ErrorFlag =
false, TooBigFlag =
false;
11957 if(!ErrorFlag && !TooBigFlag)
11967 int KPH = (MPH * 1.609344) + 0.5;
11974 int MPH = (KPH * 0.621371) + 0.5;
11985 catch(
const EConvertError &ec)
11989 catch(
const Exception &e)
12024 bool ErrorFlag =
false, TooBigFlag =
false;
12045 if(!ErrorFlag && !TooBigFlag)
12055 int KW = (HP * 0.745699872) + 0.5;
12062 int HP = (KW * 1.340482574) + 0.5;
12073 catch(
const EConvertError &ec)
12077 catch(
const Exception &e)
12090 bool ErrorFlag =
false, TooBigFlag =
false;
12111 if(!ErrorFlag && !TooBigFlag)
12121 int KPH = (MPH * 1.609344) + 0.5;
12128 int MPH = (KPH * 0.621371) + 0.5;
12139 catch(
const EConvertError &ec)
12143 catch(
const Exception &e)
12157 bool ErrorFlag =
false, TooLongFlag =
false;
12160 for(
int x = 1; x <=
MileEdit->Text.Length(); x++)
12172 for(
int x = 1; x <=
ChainEdit->Text.Length(); x++)
12184 for(
int x = 1; x <=
YardEdit->Text.Length(); x++)
12196 TooLongFlag =
true;
12199 if(!ErrorFlag && !TooLongFlag)
12201 int Miles = 0, Chains = 0, Yards = 0, Metres = 0;
12214 Metres = int((Miles * 1609.344) + (Chains * 20.1168) + (Yards * 0.9144) + 0.5);
12223 catch(
const EConvertError &ec)
12227 catch(
const Exception &e)
12258 catch(
const Exception &e)
12295 "Changes have been made to the timetable clock - you may wish to save a session before resuming operation.\n\nTo cancel all changes re-click the 'Adjust the timetable clock' button then click the reset button BEFORE resuming operation.";
12304 catch(
const Exception &e)
12322 catch(
const Exception &e)
12341 catch(
const Exception &e)
12360 catch(
const Exception &e)
12379 catch(
const Exception &e)
12398 catch(
const Exception &e)
12417 catch(
const Exception &e)
12436 catch(
const Exception &e)
12456 catch(
const Exception &e)
12475 catch(
const Exception &e)
12489 double TTClockIncrement = 1.0 / 24;
12495 catch(
const Exception &e)
12509 double TTClockIncrement = 1.0 / 144;
12515 catch(
const Exception &e)
12529 double TTClockIncrement = 1.0 / 1440;
12535 catch(
const Exception &e)
12592 catch(
const Exception &e)
12606 InfoPanel->Caption =
"PRE-START: Presetting automatic signal routes";
12617 Screen->Cursor = TCursor(-11);
12619 bool PointsChanged, AtLeastOneSet =
false;
12620 int LastIteratorValue = 0;
12629 AtLeastOneSet =
true;
12646 ShowMessage(
"No presettable automatic signal routes are available");
12648 Screen->Cursor = TCursor(-2);
12651 catch(
const Exception &e)
12666 int DispW = (
Interface->Width - 64 - 16) / 16;
12668 int DispH = (
Interface->Height - 192) / 16;
12700 catch(
const Exception &e)
12730 catch(
const Exception &e)
12756 SigImagePanel->Caption =
"Signals will be on the right hand side of the track";
12761 std::ofstream SigFile((
CurDir +
"\\Signal.hnd").c_str());
12764 ShowMessage(
"Failed to store right hand signal setting, program will default to left hand signals when next loaded");
12782 SigImagePanel->Caption =
"Signals will be on the left hand side of the track";
12787 std::ofstream SigFile((
CurDir +
"\\Signal.hnd").c_str());
12799 catch(
const Exception &e)
12818 bool TooBigFlag =
false, BadCharsFlag =
false;
12823 for(
int x = 1; x <=
MTBFEditBox->Text.Length(); x++)
12827 BadCharsFlag =
true;
12840 ShowMessage(
"Maximum value allowed is 10,000");
12849 ShowMessage(
"Value must be a whole number with no special characters");
12866 catch(
const Exception &e)
12884 "Values can only be entered or changed in Pre-Start mode\ni.e. after selecting 'Operate railway' but before clicking 'Run'");
12888 catch(
const Exception &e)
12921 catch(
const Exception &e)
12947 catch(
const Exception &e)
12963 catch(
const Exception &e)
12984 catch(
const Exception &e)
13001 catch(
const Exception &e)
13018 catch(
const Exception &e)
13034 ShowMessage(
"No boxes ticked!");
13038 Screen->Cursor = TCursor(-11);
13039 AnsiString TTTitle;
13053 ShowMessage(
"Analysis complete and file created");
13058 Screen->Cursor = TCursor(-2);
13061 catch(
const Exception &e)
13103 int WidthNum = int(
MainScreen->Width / 160) + 1;
13104 int HeightNum = int(
MainScreen->Height / 144) + 1;
13105 for(
int x = 0; x < WidthNum; x++)
13107 for(
int y = 0; y < HeightNum; y++)
13212 bool BreakFlag =
false;
13321 ZoomButton->Glyph->LoadFromResourceName(0,
"ZoomOut");
13355 InfoPanel->Caption =
"CONNECTING GAPS: Click on connecting element";
13371 UnicodeString MessageStr =
"The railway has changed, close it without saving?";
13372 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
13419 std::ifstream VecFile(FileName);
13421 if(VecFile.is_open())
13441 bool GraphicsFollow =
false;
13442 int NumberOfActiveElements;
13455 if(!(EveryPrefDir->CheckOnePrefDir(0, NumberOfActiveElements, VecFile)))
13486 TDateTime First, Second;
13487 bool Finished =
false;
13489 First = TDateTime::CurrentDateTime();
13490 double TimeVal1 = 86400000 * double(First);
13494 Second = TDateTime::CurrentDateTime();
13495 double TimeVal2 = 86400000 * double(Second);
13496 if((TimeVal2 - TimeVal1) > Msec)
13556 if((LinkNumber1 == 1) || (LinkNumber1 == 3) || (LinkNumber1 == 7) || (LinkNumber1 == 9))
13564 if((LinkNumber2 == 1) || (LinkNumber2 == 3) || (LinkNumber2 == 7) || (LinkNumber2 == 9))
13716 InfoPanel->Caption =
"Select an option from the File, Mode or Help menus";
13878 InfoPanel->Caption =
"PREFERRED DIRECTION SETTING: Select preferred direction start location (right click to erase)";
13944 MTBFLabel->Caption =
"Mean time between\ntrain failures in\ntimetable hours";
13957 OperateButton->Glyph->LoadFromResourceName(0,
"RunGraphic");
13984 ShowMessage(
"Performance logfile failed to open, logs won't be saved. Ensure that there is a folder named " +
PERFLOG_DIR_NAME +
13985 " in the folder where the 'Railway.exe' program file resides");
14026 OAListBox->Items->Add(L
"locate train");
14030 OAListBox->Items->Add(L
"headcode for");
14034 OAListBox->Items->Add(L
"Left click and");
14035 OAListBox->Items->Add(L
"hold grey area");
14036 OAListBox->Items->Add(L
"to move panel");
14070 OperateButton->Glyph->LoadFromResourceName(0,
"RunGraphic");
14095 OAListBox->Items->Add(L
"locate train");
14099 OAListBox->Items->Add(L
"headcode for");
14103 OAListBox->Items->Add(L
"Left click and");
14104 OAListBox->Items->Add(L
"hold grey area");
14105 OAListBox->Items->Add(L
"to move panel");
14119 MTBFLabel->Caption =
"Mean time between\ntrain failures in\ntimetable hours";
14128 MTBFLabel->Caption =
"Mean time between\ntrain failures in\ntimetable hours";
14165 InfoPanel->Caption =
"ADDING TRACK: Select element then left click to add it. Right click an element to remove it.";
14203 InfoPanel->Caption =
"ADDING GRAPHIC: Left click layout to add SELECTED graphic, right click to remove ANY graphic.";
14208 InfoPanel->Caption =
"SELECTING USER GRAPHIC: Select the graphic file then add as many as necessary to the layout.";
14212 int HLoc, VLoc, Count;
14214 if(div(Count, 2).rem == 1)
14216 ShowMessage(
"Can't connect, there are an odd number of gaps");
14231 ShowMessage(
"Error - Even number of gaps but all set after first call to HighLightOneGap");
14241 InfoPanel->Caption =
"CONNECTING GAPS: Click on connecting gap";
14248 InfoPanel->Caption =
"ADDING/EDITING TEXT: Left click to add, right click first letter to erase, or left click first letter to edit)";
14263 InfoPanel->Caption =
"MOVING TEXT OR GRAPHIC: If text left click first letter, if graphic left click anywhere, then drag";
14270 InfoPanel->Caption =
"NAMING LOCATIONS: Click on location element to add or change name";
14278 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Select first location (only non-default elements marked)";
14290 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Select next location";
14294 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Continue or set values (overall length), or right click to cancel/truncate";
14309 InfoPanel->Caption =
"SELECTING: Select area - click left mouse && drag";
14319 InfoPanel->Caption =
"COPYING: Left click in selection && drag";
14344 bool EraseSuccessfulFlag, NeedToLink =
false, TextChangesMade =
false, GraphicChangesMade =
false;
14346 int ErasedTrackVectorPosition;
14347 Screen->Cursor = TCursor(-11);
14349 InfoPanel->Caption =
"CUT PROCESSING: Please do not click the mouse";
14356 if(EraseSuccessfulFlag)
14358 if(ErasedTrackVectorPosition > -1)
14370 int HighSelectVPos =
SelectRect.bottom * 16;
14376 if((TextPtr->HPos >= LowSelectHPos) && (TextPtr->HPos < HighSelectHPos) && (TextPtr->VPos >= LowSelectVPos) && (TextPtr->VPos <
14384 TextChangesMade =
true;
14394 if((GraphicPtr->HPos >= LowSelectHPos) && ((GraphicPtr->HPos + GraphicPtr->Width) < HighSelectHPos) && (GraphicPtr->VPos >= LowSelectVPos)
14395 && ((GraphicPtr->VPos + GraphicPtr->Height) < HighSelectVPos))
14398 GraphicChangesMade =
true;
14405 Screen->Cursor = TCursor(-2);
14412 InfoPanel->Caption =
"CUTTING: Left click in selection && drag";
14428 if(NeedToLink || TextChangesMade || GraphicChangesMade)
14456 UnicodeString MessageStr =
14457 "Please be aware of the relevant conditions when pasting " "a railway segment from a different application.\n"
14458 "These are set out in section 3.5 of the manual and " "on-screen help under the heading 'Pasting in an application "
14459 "after cutting or copying from a different application'.\n\n" "This warning will not be shown again.\n\n" "Proceed?";
14460 int button = Application->MessageBox(MessageStr.c_str(), L
"Warning", MB_YESNO | MB_ICONWARNING);
14472 Application->MessageBoxW(L
"Unable to paste, clipboard does not contain a valid railway segment", L
"Warning", MB_OK | MB_ICONWARNING);
14485 Clipboard()->Clear();
14486 Clipboard()->Close();
14489 bool NeedToLink =
false;
14490 bool TrackLinkingRequiredFlag;
14491 Screen->Cursor = TCursor(-11);
14493 InfoPanel->Caption =
"PASTING: Please wait";
14500 bool TrackEraseSuccessfulFlag;
14501 int ErasedTrackVectorPosition;
14503 for(
int x = LowSelectHLoc; x < HighSelectHLoc; x++)
14505 for(
int y = LowSelectVLoc; y < HighSelectVLoc; y++)
14508 if(ErasedTrackVectorPosition > -1)
14525 if((TextPtr->HPos >= LowSelectHPos) && (TextPtr->HPos < HighSelectHPos) && (TextPtr->VPos >= LowSelectVPos) && (TextPtr->VPos <
14542 if((GraphicPtr->HPos >= LowSelectHPos) && ((GraphicPtr->HPos + GraphicPtr->Width) < HighSelectHPos) && (GraphicPtr->VPos >= LowSelectVPos)
14543 && ((GraphicPtr->VPos + GraphicPtr->Height) < HighSelectVPos))
14564 bool InternalChecks =
false;
14568 TrackLinkingRequiredFlag, InternalChecks);
14584 if(TrackLinkingRequiredFlag)
14595 TextPtr->HPos += HDiff * 16;
14596 TextPtr->VPos += VDiff * 16;
14597 AnsiString TempString = TextPtr->TextString;
14613 if(TextPtr->TextString.SubString(1, 4) ==
"##**")
14615 TempString = TextPtr->TextString.SubString(5, TextPtr->TextString.Length());
14618 TextPtr->TextString =
"";
14631 for(TTrack::TUserGraphicVector::iterator GraphicPtr =
Track->
SelectGraphicVector.begin(); GraphicPtr < Track->SelectGraphicVector.end();
14634 GraphicPtr->HPos += HDiff * 16;
14635 GraphicPtr->VPos += VDiff * 16;
14650 Screen->Cursor = TCursor(-2);
14670 UnicodeString MessageStr =
"Selected area will be deleted - proceed?";
14671 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
14676 bool EraseSuccessfulFlag, NeedToLink =
false, TextChangesMade =
false, GraphicChangesMade =
false;
14677 int ErasedTrackVectorPosition;
14678 Screen->Cursor = TCursor(-11);
14680 InfoPanel->Caption =
"DELETING: Please wait";
14687 if(EraseSuccessfulFlag)
14689 if(ErasedTrackVectorPosition > -1)
14701 int HighSelectVPos =
SelectRect.bottom * 16;
14707 AnsiString Check = TextPtr->TextString;
14708 if((TextPtr->HPos >= LowSelectHPos) && (TextPtr->HPos < HighSelectHPos) && (TextPtr->VPos >= LowSelectVPos) && (TextPtr->VPos <
14716 TextChangesMade =
true;
14735 if((GraphicPtr->HPos >= LowSelectHPos) && ((GraphicPtr->HPos + GraphicPtr->Width) < HighSelectHPos) && (GraphicPtr->VPos >= LowSelectVPos)
14736 && ((GraphicPtr->VPos + GraphicPtr->Height) < HighSelectVPos))
14741 if((UserGraphicPtr->HPos == GraphicPtr->HPos) && (UserGraphicPtr->VPos == GraphicPtr->VPos) &&
14742 (UserGraphicPtr->Width == GraphicPtr->Width) && (UserGraphicPtr->Height == GraphicPtr->Height) &&
14743 (UserGraphicPtr->FileName == GraphicPtr->FileName))
14746 GraphicChangesMade =
true;
14765 if(NeedToLink || TextChangesMade || GraphicChangesMade)
14769 Screen->Cursor = TCursor(-2);
14821 bool LeadingPointsAtLastElement =
false;
14824 if(LeadingPointsAtLastElement)
14826 InfoPanel->Caption =
"PREFERRED DIRECTION SETTING: Can't end on leading points, select next location or truncate";
14831 InfoPanel->Caption =
"PREFERRED DIRECTION SETTING: Select next preferred direction location (right click to truncate)";
14836 InfoPanel->Caption =
"PREFERRED DIRECTION SETTING: Add selection or select next location (right click to truncate)";
14851 InfoPanel->Caption =
"SELECTING: Select area - click left mouse && drag";
14892 OperateButton->Glyph->LoadFromResourceName(0,
"PauseGraphic");
14966 Display->
PerformanceLog(15, TimeMessage +
"Timetable clock speed changed to one sixteenth normal");
14974 if(TTClockTimeChange > 0.000347)
14977 int MinsIncrease = ((TTClockTimeChange * 1440) + 0.5);
14978 int HoursIncrease = 0;
14979 while(MinsIncrease >= 60)
14982 MinsIncrease -= 60;
14984 if(HoursIncrease == 0)
14986 TimeMessage +=
"Timetable clock incremented by " + AnsiString(MinsIncrease) +
"m";
14988 else if(MinsIncrease == 0)
14990 TimeMessage +=
"Timetable clock incremented by " + AnsiString(HoursIncrease) +
"h";
14994 TimeMessage +=
"Timetable clock incremented by " + AnsiString(HoursIncrease) +
"h " + AnsiString(MinsIncrease) +
"m";
15006 MTBFLabel->Caption =
"Mean time between\ntrain failures in\ntimetable hours";
15014 MTBFLabel->Caption =
"Mean time between\ntrain failures in\ntimetable hours";
15023 OperateButton->Glyph->LoadFromResourceName(0,
"RunGraphic");
15051 float LockDelay = 120.0;
15057 bool BreakFlag =
false;
15061 if((TTClockTime - LRVIT->LockStartTime) > TDateTime(LockDelay / 86400))
15064 AnsiString(LRVIT->LastTrackVectorPosition));
15065 while(Route.
LastElementPtr(9)->GetTrackVectorPosition() != LRVIT->TruncateTrackVectorPosition)
15082 if(Route.
LastElementPtr(17)->GetTrackVectorPosition() == LRVIT->TruncateTrackVectorPosition)
15123 int TempLockedVectorNumber;
15133 if(((TTClockTime - AutoSigVectorIT->PassoutTime) > TDateTime(AutoSigVectorIT->FirstDelay / 86400)) && (AutoSigVectorIT->AccessNumber == 0))
15136 AutoSigVectorIT->AccessNumber++;
15139 if(((TTClockTime - AutoSigVectorIT->PassoutTime) > TDateTime(AutoSigVectorIT->SecondDelay / 86400)) && (AutoSigVectorIT->AccessNumber == 1))
15142 AutoSigVectorIT->AccessNumber++;
15145 if(((TTClockTime - AutoSigVectorIT->PassoutTime) > TDateTime(AutoSigVectorIT->ThirdDelay / 86400)) && (AutoSigVectorIT->AccessNumber == 2))
15148 AutoSigVectorIT->AccessNumber++;
15156 if(AutoSigVectorIT->AccessNumber > 2)
15170 TPoint MousePoint = Mouse->CursorPos;
15171 int ScreenX = MousePoint.x -
MainScreen->ClientOrigin.x;
15172 int ScreenY = MousePoint.y -
MainScreen->ClientOrigin.y;
15184 ((MousePoint.y - ClientOrigin.y) >=
PerformancePanel->Top) && ((MousePoint.y - ClientOrigin.y) <=
15196 ((MousePoint.y - ClientOrigin.y) >=
TimetableEditPanel->Top) && ((MousePoint.y - ClientOrigin.y) <=
15205 AnsiString TrackFloat =
"", TrainStatusFloat =
"", TrainTTFloat =
"";
15206 bool ShowTrackFloatFlag =
false, ShowTrainStatusFloatFlag =
false, ShowTrainTTFloatFlag =
false;
15216 bool MouseOverOAPanel =
false;
15221 ((MousePoint.y - ClientOrigin.y) >=
OperatorActionPanel->Top) && ((MousePoint.y - ClientOrigin.y) <=
15224 MouseOverOAPanel =
true;
15230 bool ActiveTrackFoundFlag =
false, InactiveTrackFoundFlag =
false, TwoTrack =
false;
15231 AnsiString Length01Str =
"", Length23Str =
"", SpeedLimit01Str =
"", SpeedLimit23Str =
"";
15232 AnsiString StationEntryStopLinkPos1Str =
"", StationEntryStopLinkPos2Str =
"";
15233 AnsiString ATrackSN =
"", ATrackTN =
"", IATrackSN =
"", LengthAndSpeedCaption =
"";
15234 AnsiString SigAspectString =
"";
15238 if(InactiveTrackFoundFlag)
15243 if(ActiveTrackFoundFlag)
15250 if((ATrackTN !=
"") && (!InactiveTrackFoundFlag || ((InactiveTrackElement.
TrackType !=
Platform) &&
15254 ShowMessage(
"Error - Track has timetable name without corresponding plat/named loc");
15259 ShowMessage(
"Error - plat/named loc and track have different names, or plat/named loc named but not track");
15265 Length01Str = AnsiString(ActiveTrackElement.
Length01);
15266 if(Length01Str ==
"-1")
15268 Length01Str =
"Not Set";
15270 SpeedLimit01Str = AnsiString(ActiveTrackElement.
SpeedLimit01);
15271 if(SpeedLimit01Str ==
"-1")
15273 SpeedLimit01Str =
"Not Set";
15277 Length23Str = AnsiString(ActiveTrackElement.
Length23);
15278 if(Length23Str ==
"-1")
15280 Length23Str =
"Not Set";
15282 SpeedLimit23Str = AnsiString(ActiveTrackElement.
SpeedLimit23);
15283 if(SpeedLimit23Str ==
"-1")
15285 SpeedLimit23Str =
"Not Set";
15289 LengthAndSpeedCaption =
"Straight track length = " + Length01Str +
" m" +
'\n' +
"Diverging track length = " + Length23Str +
" m" +
'\n' +
15290 "Straight track speed limit = " + SpeedLimit01Str +
" km/h" +
'\n' +
"Diverging track speed limit = " + SpeedLimit23Str +
" km/h";
15294 LengthAndSpeedCaption =
"Left diverging track length = " + Length01Str +
" m" +
'\n' +
"Right diverging track length = " + Length23Str +
15295 " m" +
'\n' +
"Left diverging track speed limit = " + SpeedLimit01Str +
" km/h" +
'\n' +
"Right diverging track Speed Limit = " +
15296 SpeedLimit23Str +
" km/h";
15301 if((ActiveTrackElement.
SpeedTag == 15) || (ActiveTrackElement.
SpeedTag == 46))
15303 LengthAndSpeedCaption =
"Horizontal track length = " + Length01Str +
" m" +
'\n' +
"Other track length = " + Length23Str +
" m" +
'\n' +
15304 "Horizontal track speed limit = " + SpeedLimit01Str +
" km/h" +
'\n' +
"Other track speed limit = " + SpeedLimit23Str +
" km/h";
15306 else if(ActiveTrackElement.
SpeedTag == 47)
15308 LengthAndSpeedCaption =
"Horizontal track length = " + Length23Str +
" m" +
'\n' +
"Other track length = " + Length01Str +
" m" +
'\n' +
15309 "Horizontal track speed limit = " + SpeedLimit23Str +
" km/h" +
'\n' +
"Other track speed limit = " + SpeedLimit01Str +
" km/h";
15311 else if(ActiveTrackElement.
SpeedTag == 45)
15313 LengthAndSpeedCaption =
"Vertical track length = " + Length01Str +
" m" +
'\n' +
"Other track length = " + Length23Str +
" m" +
'\n' +
15314 "Vertical track speed limit = " + SpeedLimit01Str +
" km/h" +
'\n' +
"Other track speed limit = " + SpeedLimit23Str +
" km/h";
15316 else if(ActiveTrackElement.
SpeedTag == 44)
15318 LengthAndSpeedCaption =
"Vertical track length = " + Length23Str +
" m" +
'\n' +
"Other track length = " + Length01Str +
" m" +
'\n' +
15319 "Vertical track speed limit = " + SpeedLimit23Str +
" km/h" +
'\n' +
"Other track speed limit = " + SpeedLimit01Str +
" km/h";
15321 else if(ActiveTrackElement.
SpeedTag == 16)
15323 LengthAndSpeedCaption =
"Top left to bottom right track length = " + Length01Str +
" m" +
'\n' +
"Other track length = " + Length23Str +
15324 " m" +
'\n' +
"Top left to bottom right track speed limit = " + SpeedLimit01Str +
" km/h" +
'\n' +
"Other track speed limit = " +
15325 SpeedLimit23Str +
" km/h";
15330 LengthAndSpeedCaption =
"Top track length = " + Length01Str +
" m" +
'\n' +
"Bottom track length = " + Length23Str +
" m" +
'\n' +
15331 "Top track speed limit = " + SpeedLimit01Str +
" km/h" +
'\n' +
"Bottom track speed limit = " + SpeedLimit23Str +
" km/h";
15336 LengthAndSpeedCaption =
"Track length = " + Length01Str +
" m" +
'\n' +
"Track speed limit = " + SpeedLimit01Str +
" km/h";
15339 if(ActiveTrackFoundFlag)
15343 ShowTrackFloatFlag =
true;
15346 TrackFloat =
"Location = " + ATrackTN +
'\n' + LengthAndSpeedCaption +
'\n' +
"ID = " + AnsiString(ActiveTrackElement.
ElementID);
15348 else if(ATrackSN !=
"")
15350 TrackFloat =
"Location = " + ATrackSN +
'\n' + LengthAndSpeedCaption +
'\n' +
"ID = " + AnsiString(ActiveTrackElement.
ElementID);
15353 else if(InactiveTrackFoundFlag)
15355 TrackFloat =
"Location unnamed\n" + LengthAndSpeedCaption +
'\n' +
"ID = " + AnsiString(ActiveTrackElement.
ElementID);
15360 TrackFloat = LengthAndSpeedCaption +
'\n' +
"Track Element ID = " + AnsiString(ActiveTrackElement.
ElementID);
15366 SigAspectString =
"\nThree-aspect signal";
15370 SigAspectString =
"\nTwo-aspect signal";
15374 SigAspectString =
"\nGround signal";
15378 SigAspectString =
"\nFour-aspect signal";
15380 TrackFloat += SigAspectString;
15383 else if(InactiveTrackFoundFlag)
15386 ShowTrackFloatFlag =
true;
15389 if(IATrackSN ==
"")
15391 TrackFloat =
"Location unnamed\nID = " + AnsiString(InactiveTrackElement.
ElementID);
15395 TrackFloat =
"Location = " + IATrackSN +
'\n' +
"ID = " + AnsiString(InactiveTrackElement.
ElementID);
15400 TrackFloat =
"ID = " + AnsiString(InactiveTrackElement.
ElementID);
15406 bool OAListBoxFloatRequired =
false;
15411 AnsiString FormatOneDPStr =
"####0.0";
15412 AnsiString FormatNoDPStr =
"#######0";
15414 AnsiString MaxBrakeStr =
"";
15415 AnsiString SpecialStr =
"";
15420 int X =
OAListBox->ScreenToClient(MousePoint).x;
15421 int Y =
OAListBox->ScreenToClient(MousePoint).y;
15422 int TrainID = -1, ContinuationPos = -1;
15425 OAListBoxFloatRequired =
true;
15428 ShowTrainStatusFloatFlag =
true;
15432 ShowTrainTTFloatFlag =
true;
15434 if((TrainID > -1) && (ShowTrainStatusFloatFlag || ShowTrainTTFloatFlag))
15440 else if(ContinuationPos > -1)
15447 if(!OAListBoxFloatRequired)
15450 if(FoundFlag && !MouseOverOAPanel)
15458 ShowTrainStatusFloatFlag =
true;
15463 ShowTrainTTFloatFlag =
true;
15473 TrainStatusFloat =
"No trains expected";
15474 TrainTTFloat =
"No timetable";
15477 ShowTrainStatusFloatFlag =
true;
15481 ShowTrainTTFloatFlag =
true;
15492 AnsiString Caption;
15494 if(!ShowTrackFloatFlag && !ShowTrainStatusFloatFlag && !ShowTrainTTFloatFlag)
15500 else if(ShowTrackFloatFlag && !ShowTrainStatusFloatFlag && !ShowTrainTTFloatFlag)
15502 Caption = TrackFloat;
15504 else if(!ShowTrackFloatFlag && ShowTrainStatusFloatFlag && !ShowTrainTTFloatFlag)
15506 Caption = TrainStatusFloat;
15508 else if(ShowTrackFloatFlag && ShowTrainStatusFloatFlag && !ShowTrainTTFloatFlag)
15510 Caption = TrainStatusFloat +
'\n' +
'\n' + TrackFloat;
15512 else if(!ShowTrackFloatFlag && !ShowTrainStatusFloatFlag && ShowTrainTTFloatFlag)
15514 if(TrainStatusFloat ==
"No trains expected")
15516 Caption = TrainStatusFloat;
15520 Caption = TrainTTFloat;
15523 else if(ShowTrackFloatFlag && !ShowTrainStatusFloatFlag && ShowTrainTTFloatFlag)
15525 if(TrainStatusFloat ==
"No trains expected")
15527 Caption = TrainStatusFloat +
'\n' +
'\n' + TrackFloat;
15531 Caption = TrainTTFloat +
'\n' +
'\n' + TrackFloat;
15534 else if(!ShowTrackFloatFlag && ShowTrainStatusFloatFlag && ShowTrainTTFloatFlag)
15536 if(TrainStatusFloat ==
"No trains expected")
15538 Caption = TrainStatusFloat;
15542 Caption = TrainStatusFloat +
'\n' +
'\n' + TrainTTFloat;
15545 else if(ShowTrackFloatFlag && ShowTrainStatusFloatFlag && ShowTrainTTFloatFlag)
15547 if(TrainStatusFloat ==
"No trains expected")
15549 Caption = TrainStatusFloat +
'\n' +
'\n' + TrackFloat;
15553 Caption = TrainStatusFloat +
'\n' +
'\n' + TrainTTFloat +
'\n' +
'\n' + TrackFloat;
15556 int WindowOffsetLeft = 16;
15557 int WindowOffsetRight = 16;
15558 if(OAListBoxFloatRequired)
15560 WindowOffsetLeft = 32;
15561 WindowOffsetRight = 64;
15566 int Left = ScreenX +
MainScreen->Left + WindowOffsetRight;
15571 Left = ScreenX -
FloatingPanel->Width + 32 - WindowOffsetLeft;
15609 AnsiString &TrainTTFloat)
15618 (CTEIt->second.TrainDataEntryPtr->TrainOperatingDataVector.at(CTEIt->second.RepeatNumber).RunningEntry !=
NotStarted)))
15625 AnsiString ServiceReferenceInfo =
"";
15629 if(CTEIt->second.RepeatNumber == 0)
15633 ServiceReferenceInfo =
"\nFirst service of ref. " + TTDEPtr->
ServiceReference;
15637 ServiceReferenceInfo =
"\nFirst service";
15642 ServiceReferenceInfo =
"\nRepeat service no. " + AnsiString(CTEIt->second.RepeatNumber);
15646 ServiceReferenceInfo =
"\nRepeat service no. " + AnsiString(CTEIt->second.RepeatNumber) +
" of ref. " + TTDEPtr->
ServiceReference;
15653 ServiceReferenceInfo =
"\nService reference " + TTDEPtr->
ServiceReference;
15658 SpecialStr =
"\nTrain under signaller control";
15660 if(EntrySpeed > LineSpeedLimit)
15662 EntrySpeed = LineSpeedLimit;
15668 if(EntrySpeed > LineSpeedLimit)
15670 EntrySpeed = LineSpeedLimit;
15675 TDateTime TempTime = CTEIt->first;
15677 TrainStatusFloat = CTEIt->second.HeadCode +
": " + CTEIt->second.Description + ServiceReferenceInfo +
"\nEntry speed " +
15678 AnsiString::FormatFloat(FormatNoDPStr, EntrySpeed) +
"km/h" + SpecialStr +
"\nDelayed, was due at " +
Utilities->
Format96HHMM(TempTime);
15682 TDateTime TempTime = CTEIt->first;
15684 TrainStatusFloat = CTEIt->second.HeadCode +
": " + CTEIt->second.Description + ServiceReferenceInfo +
"\nEntry speed " +
15685 AnsiString::FormatFloat(FormatNoDPStr, EntrySpeed) +
"km/h" + SpecialStr +
"\nExpected at " +
Utilities->
Format96HHMM(TempTime);
15692 CTEIt->second.IncrementalDigits);
15706 AnsiString HeadCode =
"", ServiceReferenceInfo =
"", Status =
"", CurrSpeedStr =
"", BrakePCStr =
"", NextStopStr =
"", TimeLeftStr =
"",
15707 TimeToNextMovementStr =
"", MassStr =
"", PowerStr =
"";
15708 AnsiString FormatOneDPStr =
"####0.0", MaxBrakeStr =
"", MaxSpeedStr =
"", TrainStatusFloat;
15712 MassStr = AnsiString::FormatFloat(FormatNoDPStr, ((
double)Train.
Mass) / 1000);
15713 PowerStr = AnsiString::FormatFloat(FormatNoDPStr, Train.
PowerAtRail / 1000 / 0.8);
15716 MaxSpeedStr =
"30";
15720 MaxSpeedStr = AnsiString::FormatFloat(FormatNoDPStr, Train.
MaxRunningSpeed);
15725 TDateTime TimeLeft;
15727 MaxBrakeStr = AnsiString::FormatFloat(FormatNoDPStr, (Train.
MaxBrakeRate * Train.
Mass / 9810));
15739 ServiceReferenceInfo =
"\nFirst service";
15744 ServiceReferenceInfo =
"\nRepeat service no. " + AnsiString(Train.
RepeatNumber);
15762 Status =
"Stopped on signaller's instruction";
15766 Status =
"Not in service";
15770 Status =
"Stopped at buffers";
15774 Status =
"Stopped at signal";
15778 Status =
"Stopped - forward track occupied";
15792 Status =
"Stopped without power - train failed";
15796 Status =
"Stopped without power";
15801 Status =
"Stopped - signal passed at danger";
15805 Status =
"Derailed";
15809 Status =
"Crashed";
15817 Status =
"Accelerating";
15824 if(BrakePCRate < 55)
15826 Status =
"Light braking";
15828 else if(BrakePCRate < 90)
15830 Status =
"Heavy braking";
15834 Status =
"Emergency braking";
15841 if(BrakePCRate < 55)
15843 Status =
"Light braking";
15845 else if(BrakePCRate < 90)
15847 Status =
"Heavy braking";
15851 Status =
"Emergency braking";
15858 Status =
"Accelerating";
15864 Status =
"Accelerating";
15866 ((Train.
ExitSpeedFull - Train.
ExitSpeedHalf) * (
double(ElapsedDeltaT - FirstHalfTimeDeltaT) / double(SecondHalfTimeDeltaT)));
15875 Status =
"Coasting - train failed";
15879 Status =
"Coasting - no power";
15885 Status =
"Constant speed";
15896 Status =
"Coasting - train failed";
15900 Status =
"Coasting - no power";
15906 Status =
"Constant speed";
15914 NextStopStr =
"At signaller's discretion";
15918 NextStopStr =
"None";
15927 SpecialStr =
"Train under signaller control" + AnsiString(
'\n');
15931 SpecialStr =
"Restricted speed - being called on" + AnsiString(
'\n');
15934 if(RemTimeHalf < 0)
15939 if(RemTimeFull < 0)
15943 if(RemTimeHalf > 0)
15945 TimeLeft = RemTimeHalf;
15949 TimeLeft = RemTimeFull;
15951 TimeToNextMovementStr =
"Time to next movement (sec) = " + TimeLeftStr.FormatFloat(FormatOneDPStr, TimeLeft);
15954 TimeToNextMovementStr =
"";
15958 TrainStatusFloat = HeadCode +
": " + Train.
TrainDataEntryPtr->
Description + ServiceReferenceInfo +
'\n' +
"Maximum train speed " + MaxSpeedStr +
15959 "km/h; Power " + PowerStr +
"kW" +
'\n' +
"Mass " + MassStr +
"Te; Brakes " + MaxBrakeStr +
"Te" +
'\n' + SpecialStr + Status +
'\n' +
"Next: " +
15964 TrainStatusFloat = HeadCode +
": " + Train.
TrainDataEntryPtr->
Description + ServiceReferenceInfo +
'\n' +
"Maximum train speed " + MaxSpeedStr +
15965 "km/h; Power " + PowerStr +
"kW" +
'\n' +
"Mass " + MassStr +
"Te; Brakes " + MaxBrakeStr +
"Te" +
'\n' + SpecialStr + Status +
": " +
15966 CurrSpeedStr.FormatFloat(FormatNoDPStr, CurrSpeed) +
"km/h" +
'\n' +
"Next: " + NextStopStr;
15969 return(TrainStatusFloat);
16048 InfoPanel->Caption =
"PRE-START: Route setting in progress";
16052 InfoPanel->Caption =
"OPERATING: Route setting in progress";
16175 bool Manual =
false;
16224 throw Exception(
"Failed to find a route at LC position HLoc = " + (AnsiString)H +
" VLoc = " + (AnsiString)V);
16229 if(RouteNumber > -1)
16263 bool SaveRailwayButtonsFlag =
true;
16272 SaveRailwayButtonsFlag =
false;
16290 SaveRailwayButtonsFlag =
false;
16298 SaveRailwayButtonsFlag =
false;
16349 bool ZoomFlag =
true, HomeFlag =
true, NewHomeFlag =
true, ScreenLeftFlag =
true, ScreenRightFlag =
true, ScreenUpFlag =
true, ScreenDownFlag =
true,
16350 TrackBuildPanelEnabledFlag =
true, PrefDirPanelEnabledFlag =
true, OperatingPanelEnabledFlag =
true, TimetablePanelEnabledFlag =
true;
16352 AnsiString TrackBuildPanelLabelCaptionStr =
"Build/modify";
16353 AnsiString PrefDirPanelLabelCaptionStr =
"Preferred direction selection";
16354 AnsiString OperatingPanelLabelCaptionStr =
"Operation";
16355 AnsiString TimetablePanelLabelCaptionStr =
"Timetable editor";
16362 ScreenLeftFlag =
false;
16366 ScreenRightFlag =
false;
16370 ScreenUpFlag =
false;
16374 ScreenDownFlag =
false;
16382 ScreenLeftFlag =
false;
16386 ScreenRightFlag =
false;
16390 ScreenUpFlag =
false;
16394 ScreenDownFlag =
false;
16401 NewHomeFlag =
false;
16402 ScreenLeftFlag =
false;
16403 ScreenRightFlag =
false;
16404 ScreenUpFlag =
false;
16405 ScreenDownFlag =
false;
16410 TrackBuildPanelEnabledFlag =
false;
16411 TrackBuildPanelLabelCaptionStr =
"Disabled";
16412 PrefDirPanelEnabledFlag =
false;
16413 PrefDirPanelLabelCaptionStr =
"Disabled";
16414 OperatingPanelEnabledFlag =
false;
16415 OperatingPanelLabelCaptionStr =
"Disabled";
16416 TimetablePanelEnabledFlag =
false;
16417 TimetablePanelLabelCaptionStr =
"Disabled";
16425 OperatingPanelEnabledFlag =
false;
16426 OperatingPanelLabelCaptionStr =
"Disabled";
16429 NewHomeFlag =
false;
16430 ScreenLeftFlag =
false;
16431 ScreenRightFlag =
false;
16432 ScreenUpFlag =
false;
16433 ScreenDownFlag =
false;
16446 NewHomeFlag =
false;
16447 ScreenLeftFlag =
false;
16448 ScreenRightFlag =
false;
16449 ScreenUpFlag =
false;
16450 ScreenDownFlag =
false;
16456 NewHomeFlag =
false;
16457 ScreenLeftFlag =
false;
16458 ScreenRightFlag =
false;
16459 ScreenUpFlag =
false;
16460 ScreenDownFlag =
false;
16467 NewHomeFlag =
false;
16468 ScreenLeftFlag =
false;
16469 ScreenRightFlag =
false;
16470 ScreenUpFlag =
false;
16471 ScreenDownFlag =
false;
16510 if(ScreenRightFlag)
16534 if(OperatingPanelEnabledFlag)
16542 if(TrackBuildPanelEnabledFlag)
16550 if(PrefDirPanelEnabledFlag)
16558 if(TimetablePanelEnabledFlag)
16581 bool CallOnValid =
false;
16587 CallOnValid =
true;
16682 Screen->Cursor = TCursor(-2);
16726 Caption =
"Railway: New railway under development";
16730 Caption =
"Railway: " +
RailwayTitle +
" under development";
16824 TFont *TempFont =
new TFont;
16826 TempFont->Style.Clear();
16827 TempFont->Name =
"MS Sans Serif";
16828 TempFont->Size = 10;
16830 TempFont->Charset = (TFontCharset)(0);
16937 if(NonPrefDirChangesMade)
16962 AnsiString CurrentDateTimeStr =
"", TimetableTimeStr =
"", SessionFileStr =
"";
16963 Screen->Cursor = TCursor(-11);
16964 CurrentDateTimeStr = TDateTime::CurrentDateTime().FormatString(
"dd-mm-yyyy hh.nn.ss");
16967 TimetableTimeStr = TimetableTimeStr.SubString(1, 2) +
'.' + TimetableTimeStr.SubString(4, 2) +
'.' + TimetableTimeStr.SubString(7, 2);
16970 SessionFileStr =
LoadSessionDialog->InitialDir +
"\\Session " + CurrentDateTimeStr +
"; Timetable time " + TimetableTimeStr +
"; " +
RailwayTitle +
16972 std::ofstream SessionFile(SessionFileStr.c_str());
16973 if(!(SessionFile.fail()))
17015 SessionFile.close();
17016 DeleteFile(SessionFileStr);
17017 Screen->Cursor = TCursor(-2);
17054 SessionFile.close();
17065 Screen->Cursor = TCursor(-2);
17068 catch(
const Exception &e)
17101 Screen->Cursor = TCursor(-11);
17106 if(!(SessionFile.fail()))
17113 int LastCharBeforeFloat = TempString.LastDelimiter(
'*');
17114 if((LastCharBeforeFloat == 0) || (LastCharBeforeFloat == TempString.Length()))
17121 AnsiString FloatStr = TempString.SubString(LastCharBeforeFloat + 1, TempString.Length() - LastCharBeforeFloat);
17137 bool GraphicsFollow =
false;
17153 SessionFile.close();
17154 Screen->Cursor = TCursor(-2);
17155 ShowMessage(
"Corruption in preferred direction section of the session file, session can't be loaded");
17163 SessionFile.close();
17164 Screen->Cursor = TCursor(-2);
17165 ShowMessage(
"Corruption in route section of the session file, session can't be loaded");
17177 if(TempString ==
"***BarriersDownVector***")
17185 SessionFile.close();
17186 Screen->Cursor = TCursor(-2);
17187 ShowMessage(
"Unable to load timetable section of the session file, session can't be loaded");
17194 SessionFile.close();
17195 Screen->Cursor = TCursor(-2);
17196 throw Exception(
"TimetableTitle null in LoadSession");
17214 ShowMessage(
"Performance logfile failed to open, logs won't be saved. Ensure that there is a folder named " +
PERFLOG_DIR_NAME +
17215 " in the folder where the 'Railway.exe' program file resides");
17221 SessionFile.get(TempChar);
17222 while(!SessionFile.eof() && ((TempChar ==
'\n') || (TempChar ==
'\0')))
17224 SessionFile.get(TempChar);
17226 if(SessionFile.eof())
17230 SessionFile.close();
17242 double PowerDouble;
17252 SessionFile.get(TempChar);
17253 while(!SessionFile.eof() && ((TempChar ==
'\n') || (TempChar ==
'\0')))
17255 SessionFile.get(TempChar);
17257 if(!SessionFile.eof())
17259 if((TempChar !=
'0') && (TempChar !=
'1'))
17261 throw Exception(
"TempChar value = " + AnsiString(TempChar) +
", should be 0 or 1");
17264 if(TempChar ==
'0')
17269 SessionFile.close();
17306 ShowMessage(
"Session file integrity check failed, unable to load session.");
17308 Screen->Cursor = TCursor(-2);
17312 catch(
const Exception &e)
17314 if((e.Message.Pos(
"esource") > 0) || (e.Message.Pos(
"arameter") > 0))
17316 Screen->Cursor = TCursor(-2);
17327 UnicodeString MessageStr =
17328 "Insufficient memory available to load the file, and partial load likely to be corrupt. Application will terminate. Try loading the session as the first action after reloading the program.";
17330 Application->MessageBox(MessageStr.c_str(), L
"Out of memory", MB_OK | MB_ICONERROR);
17331 Application->Terminate();
17408 if(OpMode ==
"PreStart")
17470 AnsiString OpMode =
"";
17477 else if((OpMode !=
"PreStart") && (OpMode !=
"NotPreStart"))
17706 SessionFile.close();
17707 SessionFile.open(SessionFileStr.c_str(), std::ios_base::app | std::ios_base::binary);
17721 ShowMessage(
"Failed to open temporary timetable file. Unable to save the session");
17727 char *Buffer =
new char[10000];
17732 BytesRead = FileRead(Handle, Buffer, 10000);
17733 SessionFile.write(Buffer, BytesRead);
17734 if(BytesRead < 10000)
17742 SessionFile.close();
17743 SessionFile.open(SessionFileStr.c_str(), std::ios_base::app | std::ios_base::out);
17767 if(!FileExists(TimetableFileName))
17773 ErrorFile.open(ErrorFileStr.c_str(), std::ios_base::app | std::ios_base::binary);
17775 int Handle = FileOpen(TimetableFileName, fmOpenRead);
17782 Handle = FileOpen(TimetableFileName, fmOpenRead);
17792 char *Buffer =
new char[10000];
17797 BytesRead = FileRead(Handle, Buffer, 10000);
17798 ErrorFile.write(Buffer, BytesRead);
17799 if(BytesRead < 10000)
17808 ErrorFile.open(ErrorFileStr.c_str(), std::ios_base::app | std::ios_base::out);
17836 int TempTTFileNumber = 0;
17838 while(FileExists(
CurDir +
"\\TmpTT" + AnsiString(TempTTFileNumber) +
".tmp"))
17840 TempTTFileNumber++;
17848 if(!TTBFile.fail())
17850 char *Buffer =
new char[10000];
17851 char TempChar = (char)(SessionFile.peek());
17852 if(TempChar ==
'\n')
17854 SessionFile.get(TempChar);
17856 if(!SessionFile.getline(Buffer, 10000,
'\0'))
17865 for(
int x = 0; x < 10000; x++)
17867 if(Buffer[x] !=
'\0')
17876 while(AnsiString(Buffer) !=
"***End***")
17878 TTBFile.write(Buffer, Count);
17879 TTBFile.write(&Zero, 1);
17881 if(!SessionFile.getline(Buffer, 10000,
'\0'))
17890 for(
int x = 0; x < 10000; x++)
17892 if(Buffer[x] !=
'\0')
17906 bool GiveMessagesFalse =
false;
17907 bool CheckLocationsExistInRailwayTrue =
true;
17910 std::ifstream TTBLFile(
TempTTFileName.c_str(), std::ios_base::binary);
17911 if(TTBLFile.is_open())
17913 bool SessionFileTrue =
true;
17944 for(
int x = 0; x < NumberOfTrainEntries; x++)
17952 for(
int y = 0; y < NumberOfTrains; y++)
17977 AnsiString OutString;
17984 while(OutString !=
"***End***")
17993 if(SessionFile.fail())
17998 int NumberOfTrainEntries;
18005 for(
int x = 0; x < NumberOfTrainEntries; x++)
18007 int NumberOfTrains;
18013 for(
int y = 0; y < NumberOfTrains; y++)
18042 bool EndOfFile =
false;
18044 char *TrainTimetableString =
new char[10000];
18048 TTBLFile.getline(TrainTimetableString, 10000,
'\0');
18049 if(TTBLFile.eof() && (TrainTimetableString[0] ==
'\0'))
18056 AnsiString OneLine(TrainTimetableString);
18057 bool FinalCallTrue =
true;
18059 CheckLocationsExistInRailway))
18061 TTBLFile.getline(TrainTimetableString, 10000,
'\0');
18062 if(TTBLFile.eof() && (TrainTimetableString[0] ==
'\0'))
18065 throw Exception(
"Timetable FinalCall error - no start time on own line, Count = 0");
18067 OneLine = AnsiString(TrainTimetableString);
18073 TTBLFile.getline(TrainTimetableString, 10000,
'\0');
18074 if(TTBLFile.eof() && (TrainTimetableString[0] ==
'\0'))
18081 OneLine = AnsiString(TrainTimetableString);
18087 throw Exception(
"Timetable FinalCall error in processing one timetable line, Count = " + AnsiString(Count));
18089 if(EndOfFile && (Count < 2))
18092 throw Exception(
"Timetable FinalCall error - too few or no relevant entries, Count = " + AnsiString(Count));
18097 delete[]TrainTimetableString;
18105 ShowMessage(
"Timetable secondary integrity check failed - unable to load");
18142 bool EndOfFile =
false;
18144 char *TrainTimetableString =
new char[10000];
18148 TTBLFile.getline(TrainTimetableString, 10000,
'\0');
18149 if(TTBLFile.eof() && (TrainTimetableString[0] ==
'\0'))
18156 AnsiString OneLine(TrainTimetableString);
18157 bool FinalCallTrue =
true;
18159 CheckLocationsExistInRailway))
18161 TTBLFile.getline(TrainTimetableString, 10000,
'\0');
18162 if(TTBLFile.eof() && (TrainTimetableString[0] ==
'\0'))
18165 throw Exception(
"Timetable FinalCall error - no start time on own line, Count = 0");
18167 OneLine = AnsiString(TrainTimetableString);
18173 TTBLFile.getline(TrainTimetableString, 10000,
'\0');
18174 if(TTBLFile.eof() && (TrainTimetableString[0] ==
'\0'))
18181 OneLine = AnsiString(TrainTimetableString);
18187 throw Exception(
"Timetable FinalCall error in processing one timetable line, Count = " + AnsiString(Count));
18189 if(EndOfFile && (Count < 2))
18192 throw Exception(
"Timetable FinalCall error - too few or no relevant entries, Count = " + AnsiString(Count));
18197 delete[]TrainTimetableString;
18229 std::ifstream InFile(FileName.c_str());
18231 int NumberOfActiveElements;
18232 bool GraphicsFollow =
false;
18234 if(InFile.is_open())
18381 if((TempString !=
"***BarriersDownVector***") && (TempString !=
"***Timetable***"))
18387 if(TempString ==
"***BarriersDownVector***")
18425 ShowMessage(
"Session file failed to open - reason not known, unable to load session.");
18431 InFile.open(FileName.c_str());
18432 if(InFile.is_open())
18453 bool GraphicsFollow =
false;
18574 if((TempString !=
"***BarriersDownVector***") && (TempString !=
"***Timetable***"))
18580 if(TempString ==
"***BarriersDownVector***")
18659 InFile.get(TempChar);
18660 while(!InFile.eof() && ((TempChar ==
'\n') || (TempChar ==
'\0')))
18662 InFile.get(TempChar);
18693 double PowerDouble;
18723 AnsiString TempString =
"", Line1 =
"", Line2 =
"", Line3 =
"", Line4 =
"", Line5 =
"";
18724 char *Buffer =
new char[1000];
18727 InFile.get(TempChar);
18728 InFile.getline(Buffer, 1000);
18729 TempString = AnsiString(Buffer);
18730 while(TempString !=
"***End of performance file***")
18734 InFile.getline(Buffer, 1000);
18735 TempString = AnsiString(Buffer);
18746 AnsiString TempString =
"";
18749 InFile.get(TempChar);
18750 if(TempChar !=
'\n')
18760 while(TempString !=
"***End of performance file***")
18781 AnsiString OneLine = Text.SubString(1, Text.Pos(
'\x0D'));
18782 while((OneLine.Length() > 0) && OneLine[OneLine.Length()] <
' ')
18784 OneLine.SetLength(OneLine.Length() - 1);
18786 Text = Text.SubString(Text.Pos(
'\x0D'), Text.Length());
18787 while((Text.Length() > 0) && Text[1] <
' ')
18789 Text = Text.SubString(2, (Text.Length() - 1));
18791 OutFile << OneLine.c_str() <<
'\n';
18812 InfoPanel->Caption =
"PRE-START: Select AUTOMATIC SIGNAL ROUTE start signal, or left click points to change manually";
18816 InfoPanel->Caption =
"OPERATING: Select AUTOMATIC SIGNAL ROUTE start signal, or left click points to change manually";
18829 InfoPanel->Caption =
"PRE-START: Select PREFERRED ROUTE start signal, or left click points to change manually";
18833 InfoPanel->Caption =
"OPERATING: Select PREFERRED ROUTE start signal, or left click points to change manually";
18846 InfoPanel->Caption =
"PRE-START: Select PREFERRED ROUTE start signal, or left click points to change manually";
18850 InfoPanel->Caption =
"OPERATING: Select PREFERRED ROUTE start signal, or left click points to change manually";
18863 InfoPanel->Caption =
"PRE-START: Select UNRESTRICTED ROUTE start location, or left click points to change manually";
18867 InfoPanel->Caption =
"OPERATING: Select UNRESTRICTED ROUTE start location, or left click points to change manually";
18881 InfoPanel->Caption =
"PRE-START: Select UNRESTRICTED ROUTE start location, or left click points to change manually";
18885 InfoPanel->Caption =
"OPERATING: Select UNRESTRICTED ROUTE start location, or left click points to change manually";
18912 InfoPanel->Caption =
"Left click screen to zoom in at that position";
18917 InfoPanel->Caption =
"PAUSED: Railway state changes disabled";
18991 Screen->Cursor = TCursor(-11);
18992 AnsiString ErrorFileStr =
CurDir +
"\\errorlog.err";
18993 std::ofstream ErrorFile(ErrorFileStr.c_str());
18995 if(!(ErrorFile.fail()))
18998 int ScreenX = Mouse->CursorPos.x -
MainScreen->ClientOrigin.x;
18999 int ScreenY = Mouse->CursorPos.y -
MainScreen->ClientOrigin.y;
19000 AnsiString MouseStr =
"Posx: " + AnsiString(ScreenX) +
"; Posy: " + AnsiString(ScreenY);
19010 ErrorFile << Item.c_str() <<
'\n';
19017 ErrorFile << Item.c_str() <<
'\n';
19141 Screen->Cursor = TCursor(-2);
19158 int TempTTFileNumber = 0;
19160 while(FileExists(
CurDir +
"\\TmpTT" + AnsiString(TempTTFileNumber) +
".tmp"))
19162 TempTTFileNumber++;
19165 int InHandle = FileOpen(InFileName, fmOpenRead);
19168 while(InHandle < 0)
19170 InHandle = FileOpen(InFileName, fmOpenRead);
19175 ShowMessage(
"Failed to open timetable file, make sure it's not open in another application");
19183 while(OutHandle < 0)
19190 ShowMessage(
"Failed to save temporary timetable file, sessions can't be saved - try again, may only be a temporary problem");
19191 FileClose(InHandle);
19196 int CountIn, CountOut;
19197 char *Buffer =
new char[10000];
19201 CountIn = FileRead(InHandle, Buffer, 10000);
19202 CountOut = FileWrite(OutHandle, Buffer, CountIn);
19203 if(CountOut != CountIn)
19205 ShowMessage(
"Error in writing to the temporary timetable file, sessions can't be saved - try again, may only be a temporary problem");
19207 FileClose(InHandle);
19208 FileClose(OutHandle);
19212 if(CountIn < 10000)
19218 FileClose(InHandle);
19219 FileClose(OutHandle);
19264 int VarElements = 0;
19265 bool NamedLocPresent =
false;
19273 throw Exception(
"Error - failed to find track element at " + AnsiString(TE.
HLoc) +
" & " + AnsiString(TE.
VLoc) +
" in SetLengths");
19282 NamedLocPresent =
true;
19287 if(SpeedLimit != -1)
19294 if(SpeedLimit != -1)
19305 if((NamedLocPresent) && (VarElements > 0) && ((Distance / VarElements) < 50))
19307 ShowMessage(
"Note: Named location elements are quite short. If they are too short the simulation might depart too far from reality.");
19309 if((NamedLocPresent) && (VarElements > 0) && ((Distance / VarElements) > 200))
19311 ShowMessage(
"Note: Named location elements are quite long. If they are too long the simulation might depart too far from reality.");
19319 if((VarElements * 20) > Distance)
19321 ShowMessage(
"Required distance is less than the minimum, will set each element to the minimum (20m)");
19322 Distance = (VarElements * 20);
19324 if(VarElements == 0)
19327 ShowMessage(
"No elements selected");
19332 int RemainingDistance = Distance, RemainingVarElements = VarElements, NextLength = RemainingDistance / VarElements;
19340 if(NextLength < 20)
19366 RemainingDistance -= NextLength;
19367 RemainingVarElements--;
19368 if(RemainingVarElements > 0)
19370 NextLength = RemainingDistance / RemainingVarElements;
19398 ShowMessage(
"Nothing to save!");
19404 SaveRailwayDialog->Filter =
"Development file (*.dev)|*.dev|Railway file (*.rly)|*.rly";
19417 Screen->Cursor = TCursor(-11);
19419 AnsiString Extension =
"";
19427 if(!(VecFile.fail()))
19455 if((LastChar ==
'y') || (LastChar ==
'Y'))
19484 ShowMessage(
"File open failed prior to save");
19489 ShowMessage(
"Can't save: extension must be either '.dev', or '.rly' with railway ready for operation");
19491 Screen->Cursor = TCursor(-2);
19525 System::WideChar ValidityBuffer[14];
19526 Clipboard()->GetTextBuf(ValidityBuffer, 14);
19528 Clipboard()->Close();
19634 bool TextFound =
false;
19659 AnsiString(VPos) +
"," + AnsiString((
short)UseEnteredPosition));
19660 int VPosHi, VPosLo, TextPosHi, TextPosLo;
19663 if(!UseEnteredPosition)
19670 int Depth = abs(Font->Height);
19671 TextPosHi = VPosHi + 20;
19672 TextPosLo = VPosLo - Depth - 4;
19675 if(TextPosLo >= ScreenPosLo)
19679 else if(TextPosHi < ScreenPosHi)
19685 VPos = ScreenPosLo + 288;
19732 catch(
const Exception &e)
19809 AnsiString OpTimeToActDisplay;
19810 AnsiString OpTimeToActString;
19811 AnsiString HeadCode;
19812 float OpTimeToActFloat;
19824 HeadCode = HCandTrainPosParam.first;
19825 if(OpTimeToActFloat < 0.25)
19827 OpTimeToActString =
"NOW";
19829 else if(OpTimeToActFloat < 1)
19831 OpTimeToActString =
"<1";
19835 OpTimeToActString = AnsiString(floor(OpTimeToActFloat));
19837 if(OpTimeToActFloat < 60)
19839 OpTimeToActDisplay = HeadCode + AnsiString(
'\t') + OpTimeToActString;
19840 OAListBox->Items->Add(OpTimeToActDisplay);
19864 TPicture *PicPtr =
new TPicture;
19866 UGME.second = PicPtr;
19877 catch(
const EInvalidGraphic &e)
19880 "Incorrect file format, the file can't be loaded.\nEnsure that the file you want is a valid graphic file with extension .bmp, .gif, .jpg, or .png");
19882 catch(
const Exception &e)
19897 std::wstringstream wss;
19900 wss <<
"RlyClpBrdCopy\n";
19904 wss <<
"RlyClpBrd_Cut\n";
19909 wss << TTVIt->SpeedTag;
19911 for(
int AnsLen = 0; AnsLen <= TTVIt->ActiveTrackElementName.Length(); AnsLen++)
19913 if((TTVIt->ActiveTrackElementName).c_str()[AnsLen] !=
'\0')
19915 wss << (TTVIt->ActiveTrackElementName).c_str()[AnsLen];
19922 for(
int AnsLen = 0; AnsLen <= TTVIt->ElementID.Length(); AnsLen++)
19924 if((TTVIt->ElementID).c_str()[AnsLen] !=
'\0')
19926 wss << (TTVIt->ElementID).c_str()[AnsLen];
19933 for(
int AnsLen = 0; AnsLen <= TTVIt->LocationName.Length(); AnsLen++)
19935 if((TTVIt->LocationName).c_str()[AnsLen] !=
'\0')
19937 wss << (TTVIt->LocationName).c_str()[AnsLen];
19944 wss << TTVIt->CallingOnSet;
19946 wss << TTVIt->LCPlotted;
19948 wss << TTVIt->TempTrackMarker01;
19950 wss << TTVIt->TempTrackMarker23;
19952 wss << TTVIt->Attribute;
19954 wss << TTVIt->Conn[0];
19956 wss << TTVIt->Conn[1];
19958 wss << TTVIt->Conn[2];
19960 wss << TTVIt->Conn[3];
19962 wss << TTVIt->ConnLinkPos[0];
19964 wss << TTVIt->ConnLinkPos[1];
19966 wss << TTVIt->ConnLinkPos[2];
19968 wss << TTVIt->ConnLinkPos[3];
19970 wss << TTVIt->HLoc;
19972 wss << TTVIt->VLoc;
19974 wss << TTVIt->Length01;
19976 wss << TTVIt->Length23;
19978 wss << TTVIt->SpeedLimit01;
19980 wss << TTVIt->SpeedLimit23;
19982 wss << TTVIt->StationEntryStopLinkPos1;
19984 wss << TTVIt->StationEntryStopLinkPos2;
19986 wss << TTVIt->TrainIDOnElement;
19988 wss << TTVIt->TrainIDOnBridgeTrackPos01;
19990 wss << TTVIt->TrainIDOnBridgeTrackPos23;
19992 wss << int(TTVIt->SigAspect);
19995 wss <<
"$$$" <<
'\n';
20001 for(
int AnsLen = 0; AnsLen <= TTVIt->TextString.Length(); AnsLen++)
20003 if((TTVIt->TextString).c_str()[AnsLen] !=
'\0')
20005 wss << (TTVIt->TextString).c_str()[AnsLen];
20012 wss << TTVIt->HPos;
20014 wss << TTVIt->VPos;
20016 for(
int AnsLen = 0; AnsLen <= AnsiString(TTVIt->Font->Name).Length(); AnsLen++)
20018 if(AnsiString(TTVIt->Font->Name).c_str()[AnsLen] !=
'\0')
20020 wss << AnsiString(TTVIt->Font->Name).c_str()[AnsLen];
20027 wss << TTVIt->Font->Size;
20029 if((TTVIt->Font->Color < 0) || (TTVIt->Font->Color > 0xFFFFFF))
20035 wss << int(TTVIt->Font->Color) <<
'\n';
20037 wss << int(TTVIt->Font->Charset) <<
'\n';
20040 wss <<
"$$$" <<
'\n';
20049 wss <<
"$$$" <<
'\n';
20052 Clipboard()->Clear();
20053 Clipboard()->SetTextBuf(&(wss.str()[0]));
20054 Clipboard()->Close();
20059 catch(
const EClipboardException &e)
20064 catch(
const Exception &e)
20079 ValidResult =
false;
20080 System::WideChar *SelectVectorBuffer =
new System::WideChar[4000000];
20081 int StreamSize = 0;
20082 StreamSize = Clipboard()->GetTextBuf(SelectVectorBuffer, 4000000);
20083 Clipboard()->Clear();
20084 Clipboard()->Close();
20085 if(StreamSize < 14)
20090 std::wstringstream wss;
20091 wss << SelectVectorBuffer;
20092 ClpBrdValid = AnsiString(SelectVectorBuffer).SubString(1, 13);
20094 delete[]SelectVectorBuffer;
20101 int MarkerCounter = 0;
20103 wchar_t LineString[100];
20104 wss.getline(LineString, 100);
20108 wss.getline(LineString, 100);
20109 if(AnsiString(LineString) ==
"$$$")
20116 wss.getline(LineString, 100);
20118 wss.getline(LineString, 100);
20120 wss.getline(LineString, 100);
20123 wss.getline(LineString, 100);
20125 wss.getline(LineString, 100);
20126 TE.
LCPlotted = AnsiString(LineString).ToInt();
20127 wss.getline(LineString, 100);
20129 wss.getline(LineString, 100);
20132 wss.getline(LineString, 100);
20133 TE.
Attribute = AnsiString(LineString).ToInt();
20134 wss.getline(LineString, 100);
20135 TE.
Conn[0] = AnsiString(LineString).ToInt();
20136 wss.getline(LineString, 100);
20137 TE.
Conn[1] = AnsiString(LineString).ToInt();
20138 wss.getline(LineString, 100);
20139 TE.
Conn[2] = AnsiString(LineString).ToInt();
20140 wss.getline(LineString, 100);
20141 TE.
Conn[3] = AnsiString(LineString).ToInt();
20142 wss.getline(LineString, 100);
20143 TE.
ConnLinkPos[0] = AnsiString(LineString).ToInt();
20144 wss.getline(LineString, 100);
20145 TE.
ConnLinkPos[1] = AnsiString(LineString).ToInt();
20146 wss.getline(LineString, 100);
20147 TE.
ConnLinkPos[2] = AnsiString(LineString).ToInt();
20148 wss.getline(LineString, 100);
20149 TE.
ConnLinkPos[3] = AnsiString(LineString).ToInt();
20150 wss.getline(LineString, 100);
20151 TE.
HLoc = AnsiString(LineString).ToInt();
20152 wss.getline(LineString, 100);
20153 TE.
VLoc = AnsiString(LineString).ToInt();
20154 wss.getline(LineString, 100);
20155 TE.
Length01 = AnsiString(LineString).ToInt();
20156 wss.getline(LineString, 100);
20157 TE.
Length23 = AnsiString(LineString).ToInt();
20158 wss.getline(LineString, 100);
20160 wss.getline(LineString, 100);
20162 wss.getline(LineString, 100);
20164 wss.getline(LineString, 100);
20166 wss.getline(LineString, 100);
20168 wss.getline(LineString, 100);
20170 wss.getline(LineString, 100);
20173 wss.getline(LineString, 100);
20174 int temp = AnsiString(LineString).ToInt();
20195 AnsiString FontName;
20196 int FontSize, FontColour, FontCharset, FontStyle;
20199 wss.getline(LineString, 100);
20200 if(AnsiString(LineString) ==
"$$$")
20208 wss.getline(LineString, 100);
20209 TI.
HPos = AnsiString(LineString).ToInt();
20210 wss.getline(LineString, 100);
20211 TI.
VPos = AnsiString(LineString).ToInt();
20212 wss.getline(LineString, 100);
20213 FontName = AnsiString(LineString).c_str();
20214 wss.getline(LineString, 100);
20215 FontSize = AnsiString(LineString).ToInt();
20216 wss.getline(LineString, 100);
20217 FontColour = AnsiString(LineString).ToInt();
20218 wss.getline(LineString, 100);
20219 FontCharset = AnsiString(LineString).ToInt();
20220 wss.getline(LineString, 100);
20221 FontStyle = AnsiString(LineString).ToInt();
20223 TFont *NewFont =
new TFont;
20224 NewFont->Name = FontName;
20225 NewFont->Size = FontSize;
20226 NewFont->Color =
static_cast<TColor
>(FontColour);
20227 NewFont->Charset = FontCharset;
20233 wss.getline(LineString, 100);
20234 SelectBitmap->Height = AnsiString(LineString).ToInt();
20235 wss.getline(LineString, 100);
20237 wss.getline(LineString, 100);
20238 SelectRect.left = AnsiString(LineString).ToInt();
20239 wss.getline(LineString, 100);
20240 SelectRect.top = AnsiString(LineString).ToInt();
20241 wss.getline(LineString, 100);
20242 if(AnsiString(LineString) ==
"$$$")
20246 if(MarkerCounter == 3)
20248 ValidResult =
true;
20253 catch(
const EClipboardException &e)
20256 ValidResult =
false;
20259 catch(
const Exception &e)